3. 智能合约使用

3.1 基于Solidity智能合约案例

编写合约

基于Solidity的智能合约同基于JS的程序类似,由一系列变量和相关函数组成。如下所示为模拟简单累加器功能的智能合约。我们以此为例简单介绍基于Solidity智能合约的基本组成部分。

  1. contract Accumulator{
  2. uint32 sum = 0;
  3. function increment(){
  4. sum = sum + 1;
  5. }
  6.  
  7. function getSum() returns(uint32){
  8. return sum;
  9. }
  10.  
  11. function add(uint32 num1,uint32 num2) {
  12. sum = sum+num1+num2;
  13. }
  14. }

Accumulator合约说明:

  • 基于solidity的智能合约以关键字contract开头,类似Java等语言中的class关键字;
  • 合约内部可以有变量和函数,上述sum 为uint32类型的简单变量,Solidity智能合约还支持map等集合类型;
  • 合约允许定义执行函数以function关键字定义;

基于Solidity语言编写智能合约的详细规范参考Solidiy官方网站

编译合约

Hyperchain的智能合约的编译既可以采用Solidity官方编译器编译,也可以使用Hyperchain提供的智能合约部署JSON-RPC的接口进行编译(这种场景需要在安装Hyperchain的宿主机安装Solidity编译器sloc)。

调用Hyperchain编译Solidity智能合约命令如下:

  1. curl -X POST --data
  2. '{
  3. "jsonrpc":"2.0",
  4. "namespace":"global",
  5. "method":"contract_compileContract",
  6. "params":["contract_code"],
  7. "id":1
  8. }'

合约编译接口调用的返回如下:

  1. {
  2. "jsonrpc": "2.0",
  3. "namespace":"global",
  4. "id": 1,
  5. "code": 0,
  6. "message": "SUCCESS",
  7. "result": {
  8. "abi": [
  9. "[{\"constant\":false,\"inputs\":[{\"name\":\"num1\",\"type\":\"uint32\"},{\"name\":\"num2\",\"type\":\"uint32\"}],\"name\":\"add\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"getSum\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"increment\",\"outputs\":[],\"payable\":false,\"type\":\"function\"}]"
  10. ],
  11. "bin": [
  12. "0x60606040526000805463ffffffff1916815560ae908190601e90396000f3606060405260e060020a60003504633ad14af381146030578063569c5f6d14605e578063d09de08a146084575b6002565b346002576000805460e060020a60243560043563ffffffff8416010181020463ffffffff199091161790555b005b3460025760005463ffffffff166040805163ffffffff9092168252519081900360200190f35b34600257605c6000805460e060020a63ffffffff821660010181020463ffffffff1990911617905556"
  13. ],
  14. "types": [
  15. "Accumulator"
  16. ]
  17. }
  18. }

其中字段bin对应的内容为该合约的字节码表示,该bin内容供后续部署使用。

部署合约

Hyperchain部署Solidity命令如下:

  1. curl localhost:8081 --data '{"jsonrpc":"2.0", "namespace":"global", "method":"contract_deployContract", "params":[{
  2. "from":"0x17d806c92fa941b4b7a8ffffc58fa2f297a3bffc ",
  3. "nonce":5373500328656597,
  4. "payload":"0x60606040526000805463ffffffff1916815560ae908190601e90396000f3606060405260e060020a60003504633ad14af381146030578063569c5f6d14605e578063d09de08a146084575b6002565b346002576000805460e060020a60243560043563ffffffff8416010181020463ffffffff199091161790555b005b3460025760005463ffffffff166040805163ffffffff9092168252519081900360200190f35b34600257605c6000805460e060020a63ffffffff821660010181020463ffffffff1990911617905556",
  5. "signature":"0x388ad7cb71b1281eb5a0746fa8fe6fda006bd28571cbe69947ff0115ff8f3cd00bdf2f45748e0068e49803428999280dc69a71cc95a2305bd2abf813574bcea900",
  6. "timestamp":1487771157166000000
  7. }],"id":"1"}'

部署合约返回如下,其中result字段内容为该合约在区块链中的地址,后期对该合约的调用需要指定该合约地址。

  1. {
  2. "jsonrpc": "2.0",
  3. "namespace":"global",
  4. "id": 1,
  5. "code": 0,
  6. "message": "SUCCESS",
  7. "result": "0x406f89cb205e136411fd7f5befbf8383bbfdec5f6e8bcfe50b16dcff037d1d8a"
  8. }

调用合约

Hyperchain调用命令如下,其中payload为调用合约中函数以及其参数值的编码结果,to为所调用合约的地址。

  1. curl localhost:8081 --data
  2.  
  3. '{
  4. "jsonrpc":"2.0",
  5. "namespace":"global",
  6. "method": "contract_invokeContract",
  7. "params":[{
  8. "from":"0x17d806c92fa941b4b7a8ffffc58fa2f297a3bffc",
  9. "nonce":5019420501875693,
  10. "payload":"0x3ad14af300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
  11. "signature":"0xde467ec4c0bd9033bdc3b6faa43a8d3c5dcf393ed9f34ec1c1310b0859a0ecba15c5be4480a9ad2aaaea8416324cb54e769856775dd5407f9fd64f0467331c9301",
  12. "simulate":false,
  13. "timestamp":1487773188814000000,
  14. "to":"0x313bbf563991dc4c1be9d98a058a26108adfcf81"
  15. }],
  16. "id":"1"
  17. }'

合约调用会立即给客户端返回该交易的哈希值,后期可以根据该交易的哈希值查询具体交易的执行结果。

  1. {
  2. "jsonrpc":"2.0",
  3. "namespace":"global",
  4. "id":1,
  5. "code":0,
  6. "message":"SUCCESS",
  7. "result":"0xd7a07fbc8ea43ace5c36c14b375ea1e1bc216366b09a6a3b08ed098995c08fde"
  8. }