智能合约如何返回Struct结构并通过web3获取

张亚宁   |     |   3091 次阅读

概要

可以通过返回单独的变量来返回struct结构。

启动geth节点

通过以下命令启动geth console dev节点。

geth --datadir ~/devdata --dev --nodiscover \
  --mine --minerthreads 1 --port 30301      \
  --maxpeers 0 --verbosity 3 --rpc console

合约代码

contract SalaryInfo {
    struct User {
        uint salaryId;
        string name;
        string userAddress;
        uint salary;
    }
    User[] public users;

    function addUser(uint _salaryId, string _name, string _userAddress, uint _salary) public returns(uint) {
        users.length++;
        users[users.length-1].salaryId = _salaryId;
        users[users.length-1].name = _name;
        users[users.length-1].userAddress = _userAddress;
        users[users.length-1].salary = _salary;
        return users.length;
    }

    function getUsersCount() public constant returns(uint) {
        return users.length;
    }

    function getUser(uint index) public constant returns(uint, string, string, uint) {
        return (users[index].salaryId, users[index].name, users[index].userAddress, users[index].salary);
    }
}

扁平化合约代码

可以使用stripCrLf命令

> var salaryInfoSource='contract SalaryInfo { struct User { uint salaryId; string name; string userAddress; uint salary; } User[] public users; function addUser(uint _salaryId, string _name, string _userAddress, uint _salary) public returns(uint) { users.length++; users[users.length-1].salaryId = _salaryId; users[users.length-1].name = _name; users[users.length-1].userAddress = _userAddress; users[users.length-1].salary = _salary; return users.length; } function getUsersCount() public constant returns(uint) { return users.length; } function getUser(uint index) public constant returns(uint, string, string, uint) { return (users[index].salaryId, users[index].name, users[index].userAddress, users[index].salary); }}'

部署合约到geth

var salaryInfoCompiled = web3.eth.compile.solidity(salaryInfoSource);

运行以下代码

> var salaryInfoContract = web3.eth.contract(salaryInfoCompiled.SalaryInfo.info.abiDefinition);
> var salaryInfo = salaryInfoContract.new({from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 1000000}, 
  function(e, contract) {
    if (!e) {
      if(!contract.address) {
        console.log("Contract transaction send: TransactionHash: " + 
          contract.transactionHash + " waiting to be mined...");
      } else {
        console.log("Contract mined! Address: " + contract.address);
        console.log(contract);
      }
    }
  }
)

日志中出现以下,表示合约已经部署到geth上

I0505 09:12:15.712867   27030 xeth.go:1026] Tx(0x7747500b881c8da44efbc3b5d1c2c762f1cd52d2dd74050edbfed10e51a29d8a) created: 0x0bb1d7a6b31f7a7e23e6d902bac0eb5f9c721c54
Contract transaction send: TransactionHash: 0x7747500b881c8da44efbc3b5d1c2c762f1cd52d2dd74050edbfed10e51a29d8a waiting to be mined...
...
Contract mined! Address: 0x0bb1d7a6b31f7a7e23e6d902bac0eb5f9c721c54
[object Object]

添加用户

> salaryInfo.addUser(123, "User 123", "123 drive way, the uncentralised kingdom", 100, {from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 500000});
"0x7c22797d6b7717beb398a65159b1009fba3bbc9e4917ee1584bed60ea74eac11"
> salaryInfo.addUser(234, "User 234", "234 drive way, the uncentralised kingdom", 200, {from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 500000});
"0xed197c9a6fbc70c19cc95bcdc6943e38736c080052e9e1a4f7562216d6de4c78"

获取数据

> var numberOfUsers = salaryInfo.getUsersCount();
undefined
> numberOfUsers
2
> salaryInfo.getUser(0)
[123, "User 123", "123 drive way, the uncentralised kingdom", 100]
> var user2 = salaryInfo.getUser(1);
undefined

> user2
[234, "User 234", "234 drive way, the uncentralised kingdom", 200]

亲测可行!

链接:
http://ethereum.stackexchange.com/questions/3609/returning-a-struct-and-reading-via-web3