- https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts
- https://decentralize.today/introducing-perigord-golang-tools-for-ethereum-dapp-development-60556c2d9fd
简单存储.sol:
pragma solidity ^0.4.4;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public constant returns (uint) {
return storedData;
}
}
绑定/SimpleStorage.go:
// Set is a paid mutator transaction binding the contract method 0x60fe47b1.
//
// Solidity: function set(x uint256) returns()
func (_SimpleStorage *SimpleStorageSession) Set(x *big.Int) (*types.Transaction, error) {
return _SimpleStorage.Contract.Set(&_SimpleStorage.TransactOpts, x)
}
// Solidity: function set(x uint256) returns()
func (_SimpleStorage *SimpleStorageTransactor) Set(opts *bind.TransactOpts, x *big.Int) (*types.Transaction, error) {
return _SimpleStorage.contract.Transact(opts, "set", x)
}
// Solidity: function get() constant returns(uint256)
func (_SimpleStorage *SimpleStorageSession) Get() (*big.Int, error) {
return _SimpleStorage.Contract.Get(&_SimpleStorage.CallOpts)
}
// Get is a free data retrieval call binding the contract method 0x6d4ce63c.
//
// Solidity: function get() constant returns(uint256)
func (_SimpleStorage *SimpleStorageCaller) Get(opts *bind.CallOpts) (*big.Int, error) {
var (
ret0 = new(*big.Int)
)
out := ret0
err := _SimpleStorage.contract.Call(opts, out, "get")
return *ret0, err
}
测试/SimpleStorage.go:
// TestGet checks if Get return a value that has been set
func (s *SimpleStorageSuite) TestGet(c *check.C) {
session := contract.Session("SimpleStorage")
c.Assert(session, check.NotNil)
storageSession, ok := session.(*bindings.SimpleStorageSession)
c.Assert(ok, check.Equals, true)
c.Assert(storageSession, check.NotNil)
fmt.Printf("session: %+v\n", storageSession)
tx, err := storageSession.Set(big.NewInt(2302))
c.Assert(err, check.IsNil)
c.Assert(tx, check.NotNil)
fmt.Printf("tx: %+v\n", tx)
fmt.Printf("tx.To: %v\n", tx.To())
storedData, err := storageSession.Get()
fmt.Printf("%d\n", storedData)
c.Assert(err, check.IsNil)
c.Assert(storedData, check.Equals, 2302)
}
geth
使用此脚本启动:
geth --datadir $DIR --nodiscover --maxpeers 0 init $DIR/genesis.json
geth --datadir $DIR --nodiscover --maxpeers 0 --mine --minerthreads 1 --rpc --rpcapi "eth,web3,personal,net" console
问题:运行perigord test
给了我结果:
----------------------------------------------------------------------
FAIL: tests/SimpleStorage.go:37: SimpleStorageSuite.TestGet
tests/SimpleStorage.go:55:
c.Assert(storedData, check.Equals, 2302)
... obtained *big.Int = 0 (%!q(big.Int=0))
... expected int = 2302
OOPS: 0 passed, 1 FAILED
为什么get()
返回 0 而不是 2302?
通过打印交易,我看到了:
TX(555ca4c3edfa0190ce41bb6bfced502d903a721b02113634bbab5ff48902503a)
Contract: false
From: 945cd603a6754cb13c3d61d8fe240990f86f9f8a
To: c4b69e1de27994a2a769302c4b9e7f56fa65d8d9
Nonce: 83
GasPrice: 0x430e23400
GasLimit 0xa2be
Value: 0x0
Data: 0x60fe47b100000000000000000000000000000000000000000000000000000000000008fe
V: 0x1b
R: 0x43b542cd09feb08db234a7693ed756cead678e0cf7b11b749594e9559333f7bb
S: 0x143f01822afe5d8ea65f97078b2df95df80128842a42d1f40edf031691df6bf8
Hex: f88853850430e2340082a2be94c4b69e1de27994a2a769302c4b9e7f56fa65d8d980a460fe47b100000000000000000000000000000000000000000000000000000000000008fe1ba043b542cd09feb08db234a7693ed756cead678e0cf7b11b749594e9559333f7bba0143f01822afe5d8ea65f97078b2df95df80128842a42d1f40edf031691df6bf8
如果我试图获取To
地址的值:
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.3-stable/darwin-amd64/go1.10.1
coinbase: 0x945cd603a6754cb13c3d61d8fe240990f86f9f8a
at block: 7189 (Thu, 26 Apr 2018 20:07:44 +07)
datadir: /tmp/geth_private_testnet
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
> eth.getStorageAt("0xc4b69e1de27994a2a769302c4b9e7f56fa65d8d9", 0)
"0x00000000000000000000000000000000000000000000000000000000000008fe"
和:
Python 2.7.14 (default, Mar 22 2018, 14:43:05)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int("0x00000000000000000000000000000000000000000000000000000000000008fe", 16)
2302