- A+
所属分类:区块链技术
Solidity 关于References和 Mapping的一个坑
判断一下Sample是否会正确更新doOnce
contract Sample {
mapping (uint => bool) doOnce;
uint _actionNumber;
function() {
var a = doOnce[_actionNumber];
if (a == true) { throw; }
a = true;
_actionNumber++;
}
function get(uint i) return (bool b){
b = doOnce[i];
}
}
编译sol
$ solc_helper Sample.sol
======= Sample =======
Gas estimation:
construction:
42 + 12000 = 12042
external:
fallback: 20332
internal:
(): [???]
-------------------------------------
Enter Gas:
300000
Enter Value To Be Transferred:
Enter Input:
loadScript('/Users/u2/cryptape/ethereum-bootstrap/Sample_compiled.js')
在geth中加载
> loadScript('/Users/u2/cryptape/ethereum-bootstrap/Sample_compiled.js')
null
I0824 10:01:31.023238 eth/api.go:1191] Tx(0xb2d1de4cfb6ab1f9eecf9a086b9c7d311051186d60c3856032c3bfb5ffd41794) created: 0xadff100480afd5e6eb6ccc062872cb37cebeb786
Contract transaction send: TransactionHash: 0xb2d1de4cfb6ab1f9eecf9a086b9c7d311051186d60c3856032c3bfb5ffd41794 waiting to be mined...
Compiled Object : SampleCompiled
Contract : SampleContract
Contract Instance : Sample
true
> I0824 10:01:38.891388 miner/miner.go:119] Starting mining operation (CPU=4 TOT=5)
I0824 10:01:38.892233 miner/worker.go:573] commit new work on block 381 with 2 txs & 1 uncles. Took 809.825µs
I0824 10:01:38.918238 miner/worker.go:339] 🔨 Mined block (#381 / 063f834c). Wait 5 blocks for confirmation
测试下:
> Sample
{
abi: [{
constant: false,
inputs: [{...}],
name: "get",
outputs: [{...}],
type: "function"
}],
address: "0xadff100480afd5e6eb6ccc062872cb37cebeb786",
transactionHash: "0xb2d1de4cfb6ab1f9eecf9a086b9c7d311051186d60c3856032c3bfb5ffd41794",
allEvents: function(),
get: function()
}
> Sample.get.call(1)
false
> Sample.get.call(0)
false
> web3.eth.sendTransaction({from: web3.eth.accounts[0],to: Sample.address})
I0824 10:03:18.703757 eth/api.go:1193] Tx(0x9ab493c551ec66c1eb262920b856f75f32690c4fb76175890ad63598833f6c31) to: 0xadff100480afd5e6eb6ccc062872cb37cebeb786
"0x9ab493c551ec66c1eb262920b856f75f32690c4fb76175890ad63598833f6c31"
> Sample.get.call(0)
false
> Sample.get.call(1)
false
保存bool失败
更新后doOnce
contract Sample {
struct info { bool doOnce; }
mapping (uint => info) infoMap;
uint _actionNumber;
function() {
var a = infoMap[_actionNumber];
if (a.doOnce == true) { throw; }
a.doOnce = true;
_actionNumber++;
}
function get(uint i) returns (bool b){
var a = infoMap[i];
b = a.doOnce;
}
}
$ solc_helper Sample.sol
======= Sample =======
Gas estimation:
construction:
57 + 26600 = 26657
external:
get(uint256): 40412
fallback: 40471
internal:
(): [???]
-------------------------------------
Enter Gas:
400000
Enter Value To Be Transferred:
Enter Input:
loadScript('/Users/u2/cryptape/ethereum-bootstrap/Sample_compiled.js')
> loadScript('/Users/u2/cryptape/ethereum-bootstrap/Sample_compiled.js')
null
I0824 10:13:05.568238 eth/api.go:1191] Tx(0x77e7e8a347bff1b39e44b6873b6eda4b683e066ec24e8c112cfc7d6603fedf47) created: 0x9b850aa0a0e3b982d1f1cd6b86284eda8288337e
Contract transaction send: TransactionHash: 0x77e7e8a347bff1b39e44b6873b6eda4b683e066ec24e8c112cfc7d6603fedf47 waiting to be mined...
Compiled Object : SampleCompiled
Contract : SampleContract
Contract Instance : Sample
true
> Sample
{
abi: [{
constant: false,
inputs: [{...}],
name: "get",
outputs: [{...}],
type: "function"
}],
address: "0x9b850aa0a0e3b982d1f1cd6b86284eda8288337e",
transactionHash: "0x77e7e8a347bff1b39e44b6873b6eda4b683e066ec24e8c112cfc7d6603fedf47",
allEvents: function(),
get: function()
}
> web3.eth.sendTransaction({from: web3.eth.accounts[0], to: Sample.address})
I0824 10:14:10.042082 eth/api.go:1193] Tx(0x4b92674cca27f9fac042cea3fcdecb946e032de831443185cdd5975dc5cd511d) to: 0x9b850aa0a0e3b982d1f1cd6b86284eda8288337e
"0x4b92674cca27f9fac042cea3fcdecb946e032de831443185cdd5975dc5cd511d"
> web3.eth.sendTransaction({from: web3.eth.accounts[0], to: Sample.address})
I0824 10:14:22.123947 eth/api.go:1193] Tx(0x200e9ad61ce1bff0344935ae6baa8ebdfb0a217e1bfd1bd2a0f86ea6914c3470) to: 0x9b850aa0a0e3b982d1f1cd6b86284eda8288337e
"0x200e9ad61ce1bff0344935ae6baa8ebdfb0a217e1bfd1bd2a0f86ea6914c3470"
> Sample.get.call(0)
true
> Sample.get.call(1)
false
> web3.eth.sendTransaction({from: web3.eth.accounts[0], to: Sample.address})
> Sample.get.call(1)
true
另外在某些情况下Geth和TestRPC是不同的:
https://github.com/u2/ether-router/blob/master/test/list.js
https://github.com/u2/ether-router/blob/master/test/sample.js
Sample的测试情况是Geth和TestRPC是一致的。
但是List的Geth和TestRPC是不一致的
> List.getAll.call(0)
[]
> List.setList.sendTransaction(0,[1,2,3],{from: web3.eth.accounts[0]})
I0824 10:56:29.761988 eth/api.go:1193] Tx(0x0ada2217b60f6ee69a0de3f1ea0d8c6d0858c228c9a543efe3e0a5bc3597171f) to: 0xd4f3bd8466d1b8e326db1fbf13505b3869e1083d
"0x0ada2217b60f6ee69a0de3f1ea0d8c6d0858c228c9a543efe3e0a5bc3597171f"
> web3.eth.getTransaction('0x0ada2217b60f6ee69a0de3f1ea0d8c6d0858c228c9a543efe3e0a5bc3597171f')
{
blockHash: "0x16969fec496c7507c788d799c70227a622b5ec0ab30ff7d55acd1c590a45cbb5",
blockNumber: 429,
from: "0x7d1ca639d49cf648a97ebb630564abb5c9bd75ec",
gas: 90000,
gasPrice: 20000000000,
hash: "0x0ada2217b60f6ee69a0de3f1ea0d8c6d0858c228c9a543efe3e0a5bc3597171f",
input: "0xb8c58128000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
nonce: 36,
to: "0xd4f3bd8466d1b8e326db1fbf13505b3869e1083d",
transactionIndex: 0,
value: 0
}
> List.getAll.call(0)
[]

共识社
用手机扫一扫,加入组织,时刻关注组织动态。