一步一步学区块链(5)智能合约

以太坊区块链技术2.0版本对于行业应用的开发最主要特性就是实现了智能合约,本质上讲智能合约是由事件驱动的、
具有状态的、运行在一个复制的、分享的账本之上的、且能够保管账本上资产的程序。
它是一个可以被信任,总是按照事先的规则执行的操作。但与此同时,智能合约部署完之后无法修改也会带来其他问题,这是另一个议题。下面直接上干货。
本篇内容是基于go客户端通过命令行完成智能合约的编写、发布、调用。
可参考的项目地址:http://www.ethdocs.org/en/latest/contracts-and-transactions/contracts.html

1、安装solidity智能合约开发语言 
brew tap ethereum/ethereum
brew install solidity
which solc
2、打开命令行,进入之前创建的私链,并设置日志输出文件
jwter-WIFI:csdnBlog jwter$ geth --datadir "privateChain" console 2>> log_output
Welcome to the Geth JavaScript console!

instance: Geth/v1.4.18-stable-c72f5459/darwin/go1.7.3
coinbase: 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
at block: 164 (Sat, 03 Dec 2016 16:29:24 CST)
 datadir: privateChain
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0


> 

3、设置编译环境

> web3.eth.getCompilers()
["Solidity"]
> admin.setSolc("/usr/local/bin/solc")
"solc, the solidity compiler commandline interface\nVersion: 0.4.2+commit.af6afb04.Darwin.appleclang
\n\npath: /usr/local/bin/solc"
4、编写智能合约并编译
> contractSource  = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
"contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
> contract = eth.compile.solidity(contractSource).test
{
  code: "0x606060405260308060106000396000f3606060405260e060020a6000350463c6888fa18114601c575b6002565b3
46002576007600435026060908152602090f3",
  info: {
    abiDefinition: [{
        constant: false,
        inputs: [...],
        name: "multiply",
        outputs: [...],
        payable: false,
        type: "function"
    }],
    compilerOptions: "--bin --abi --userdoc --devdoc --add-std --optimize -o /var/folders/c6/
1vhz7hcd7w9g883rwrn4vzvr0000gn/T/solc271136546",
    compilerVersion: "0.4.2",
    developerDoc: {
      methods: {}
    },
    language: "Solidity",
    languageVersion: "0.4.2",
    source: "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }",
    userDoc: {
      methods: {}
    }
  }
}
5、定义智能合约abi并编译
> abi = [{constant:false , inputs:{name:'a',type:'uint256'}}]
[{
    constant: false,
    inputs: {
      name: "a",
      type: "uint256"
    }
}]
> myabi = eth.contract(abi)
6、部署前准备:解锁账户、监控日志文件
> accountAddress = eth.accounts[0]
"0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9"
> personal.unlockAccount(accountAddress)
Unlock account 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
Passphrase: 
true
>
监控日志文件需新开窗口,执行以下命令。用于查看部署完的智能合约是否被同步到区块链网路中
jwter-WIFI:csdnBlog jwter$ tail -f log_output
7、部署智能合约
> myContract = myabi.new({from:accountAddress,data:contract.code})
{
  abi: [{
      constant: false,
      inputs: {
        name: "a",
        type: "uint256"
      }
  }],
  address: undefined,
  transactionHash: "0xf330f4affd3989d72a979410e3a53f3a4d2d4d832faaa6c1bb32f72998acbd4b"
}
8、查看部署状态,并同步到区块链中智能合约必须开始挖矿模式才是被同步到区块链中
可根据监控日志窗口可以看到交易是否执行,来决定何时执行miner.stop()
> txpool.status
{
  pending: 1,
  queued: 0
}
> miner.start()
true
> miner.stop()
true
> txpool.status
{
  pending: 0,
  queued: 0
}
9、调用智能合约
> contractABI = eth.contract(contract.info.abiDefinition)
> 
> testContract = contractABI.at(myContract.address)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  address: "0xcb0895d4b3b35b2a45a31fab853614c14e7759a4",
  transactionHash: null,
  allEvents: function(),
  multiply: function()
}
> testContract.multiply.call(3)
21

注意:记得保存智能合约部署完的地址,以及abi参数,因为部署完之后无法修改,
忘记地址则无法再次调用,同时部署智能合约会消耗gas,完成后可观察用户的余额是否变化。



阅读更多

更多精彩内容