智能合约部署及调用

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

1、安装solidity智能合约开发语言 
[plain]  view plain  copy
  1. brew tap ethereum/ethereum  
  2. brew install solidity  
  3. which solc  
2、打开命令行,进入之前创建的私链,并设置日志输出文件
[plain]  view plain  copy
  1. jwter-WIFI:csdnBlog jwter$ geth --datadir "privateChain" console 2>> log_output  
  2. Welcome to the Geth JavaScript console!  
  3.   
  4. instance: Geth/v1.4.18-stable-c72f5459/darwin/go1.7.3  
  5. coinbase: 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9  
  6. at block: 164 (Sat, 03 Dec 2016 16:29:24 CST)  
  7.  datadir: privateChain  
  8.  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  
  9.   
  10.   
  11. >   

3、设置编译环境

[plain]  view plain  copy
  1. > web3.eth.getCompilers()  
  2. ["Solidity"]  
  3. > admin.setSolc("/usr/local/bin/solc")  
  4. "solc, the solidity compiler commandline interface\nVersion: 0.4.2+commit.af6afb04.Darwin.appleclang  
  5. \n\npath: /usr/local/bin/solc"  
4、编写智能合约并编译
[plain]  view plain  copy
  1. > contractSource  = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"  
  2. "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"  
  3. > contract = eth.compile.solidity(contractSource).test  
  4. {  
  5.   code: "0x606060405260308060106000396000f3606060405260e060020a6000350463c6888fa18114601c575b6002565b3  
  6. 46002576007600435026060908152602090f3",  
  7.   info: {  
  8.     abiDefinition: [{  
  9.         constant: false,  
  10.         inputs: [...],  
  11.         name: "multiply",  
  12.         outputs: [...],  
  13.         payable: false,  
  14.         type: "function"  
  15.     }],  
  16.     compilerOptions: "--bin --abi --userdoc --devdoc --add-std --optimize -o /var/folders/c6/  
  17. 1vhz7hcd7w9g883rwrn4vzvr0000gn/T/solc271136546",  
  18.     compilerVersion: "0.4.2",  
  19.     developerDoc: {  
  20.       methods: {}  
  21.     },  
  22.     language: "Solidity",  
  23.     languageVersion: "0.4.2",  
  24.     source: "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }",  
  25.     userDoc: {  
  26.       methods: {}  
  27.     }  
  28.   }  
  29. }  

单源编译器输出会给出你合约对象,每个都代表一个单独的合约。eth.compile.solidity 的实际返还值是合约名字到合约对象的映射。由于合约名字是test,eth.compile.solidity(source).test会给出包含下列领域的测试合约对:

  • Code 编译的以太坊虚拟机字节代码
  • Info 从编译器输出的额外元数据
  • Source 源代码
  • Language 合约语言 (Solidity,Serpent,LLL)
  • LanguageVersion 合约语言版本
  • compilerVersion 用于编译这个合约的solidity编译器版本。
  • abiDefinition 应用的二进制界面定义
  • userDoc 用户的NatSpec Doc。
  • developerDoc 开发者的NatSpec Doc。

编译器输出的直接结构化(到code和info)反映了两种非常不同的部署路径。编译的以太坊虚拟机代码和一个合约创建交易被发送到区块,剩下的(info)在理想状态下会存活在去中心化云上,公开验证的元数据则执行区块链上的代码。

如果你的源包含多个合约,输出会包括每个合约一个入口,对应的合约信息对象可以用作为属性名称的合约名字检索到。你可以通过检测当前的GlobalRegistrar代码来试一下:


contracts = eth.compile.solidity(globalRegistrarSrc)

5、定义智能合约abi并编译

[plain]  view plain  copy
  1. > abi = [{constant:false , inputs:{name:'a',type:'uint256'}}]  
  2. [{  
  3.     constant: false,  
  4.     inputs: {  
  5.       name: "a",  
  6.       type: "uint256"  
  7.     }  
  8. }]  
  9. > myabi = eth.contract(abi)  
6、部署前准备:解锁账户、监控日志文件
[plain]  view plain  copy
  1. > accountAddress = eth.accounts[0]  
  2. "0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9"  
  3. > personal.unlockAccount(accountAddress)  
  4. Unlock account 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9  
  5. Passphrase:   
  6. true  
  7. >  
监控日志文件需新开窗口,执行以下命令。用于查看部署完的智能合约是否被同步到区块链网路中
[plain]  view plain  copy
  1. jwter-WIFI:csdnBlog jwter$ tail -f log_output  
7、部署智能合约
[plain]  view plain  copy
  1. > myContract = myabi.new({from:accountAddress,data:contract.code})  
  2. {  
  3.   abi: [{  
  4.       constant: false,  
  5.       inputs: {  
  6.         name: "a",  
  7.         type: "uint256"  
  8.       }  
  9.   }],  
  10.   address: undefined,  
  11.   transactionHash: "0xf330f4affd3989d72a979410e3a53f3a4d2d4d832faaa6c1bb32f72998acbd4b"  
  12. }  
8、查看部署状态,并同步到区块链中智能合约必须开始挖矿模式才是被同步到区块链中
可根据监控日志窗口可以看到交易是否执行,来决定何时执行miner.stop()
[plain]  view plain  copy
  1. > txpool.status  
  2. {  
  3.   pending: 1,  
  4.   queued: 0  
  5. }  
  6. > miner.start()  
  7. true  
  8. > miner.stop()  
  9. true  
  10. > txpool.status  
  11. {  
  12.   pending: 0,  
  13.   queued: 0  
  14. }  
9、调用智能合约
[plain]  view plain  copy
  1. > contractABI = eth.contract(contract.info.abiDefinition)  
  2. >   
  3. > testContract = contractABI.at(myContract.address)  
  4. {  
  5.   abi: [{  
  6.       constant: false,  
  7.       inputs: [{...}],  
  8.       name: "multiply",  
  9.       outputs: [{...}],  
  10.       payable: false,  
  11.       type: "function"  
  12.   }],  
  13.   address: "0xcb0895d4b3b35b2a45a31fab853614c14e7759a4",  
  14.   transactionHash: null,  
  15.   allEvents: function(),  
  16.   multiply: function()  
  17. }  
  18. > testContract.multiply.call(3)  
  19. 21  

注意:记得保存智能合约部署完的地址,以及abi参数,因为部署完之后无法修改,

忘记地址则无法再次调用,同时部署智能合约会消耗gas,完成后可观察用户的余额是否变化。

原文链接:http://blog.csdn.net/jwter87/article/details/53445709

猜你喜欢

转载自blog.csdn.net/u013127850/article/details/77247723
今日推荐