本文实现以下目标:

  1. 搭建一条以太坊私链
  2. 用企业级开发方式开发、部署一个项目
  3. 分析truffle执行过程
  4. solidity、web3等的一些说明

Token ERC20标准

contract ERC20Interface {function totalSupply() public constant returns (uint);function balanceOf(address tokenOwner) public constant returns (uint balance);function allowance(address tokenOwner, address spender) public constant returns (uint remaining);function transfer(address to, uint tokens) public returns (bool success);function approve(address spender, uint tokens) public returns (bool success);function transferFrom(address from, address to, uint tokens) public returns (bool success);event Transfer(address indexed from, address indexed to, uint tokens);event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

整个区块链的所有数据都存储在一个levelDB的数据库中,其物理文件存储在:~/Library/Ethereum/geth/chaindata/ 下。

搭建以太坊私链

1、创建目录eth

mkdir eth

2、编写创世区块,放入eth目录下。

{"config": {"chainId": 10,"homesteadBlock": 0,"eip155Block": 0,"eip158Block": 0},"alloc"      : {},"coinbase"   : "0x0000000000000000000000000000000000000000","difficulty" : "0x20000","extraData"  : "","gasLimit"   : "0xffffffff","nonce"      : "0x0000000000000042","mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000","parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000","timestamp"  : "0x00"
}

其中,alloc用来预设账号和账号的以太币数量,此处不预设,需要的时候再创建。

  • [ ] 注意

gasLimit要修改大点,不然部署智能合约的时候,合约需要消耗的gas超过这个limit会发生失败。

chainId是EIP155里定义的发送交易到哪种链的方式,(EIP是以太坊改进建议)。这里设置为10,truffle.js里的network_id也得是10,不然交易的时候会报invalid sender的错误。

CHAIN_ID Chain(s)
1 Ethereum mainnet
2 Morden (disused), Expanse mainnet
3 Ropsten
4 Rinkeby
30 Rootstock mainnet
31 Rootstock testnet
42 Kovan
61 Ethereum Classic mainnet
62 Ethereum Classic testnet
1337 Geth private chains (default)

3、创建创世块

geth --datadir "./" init genesis.json

--datadir是指定区块链数据和账户的存储目录。\
这句话的作用是:\
创建2个数据库chaindata和lightchaindata,并把genesis.json的数据分别写入这两个leveldb中。

4、启动以太坊,日志写入文件,同时进入js交互控制台。

geth --datadir "./" --rpc --rpccorsdomain="*"  console 2>>00.glog

rpccorsdomain是允许chrome插件MetaMask,remix等跨域访问web3接口。

现在这条私链上没有账户没有交易。

5、在启动矿工进行挖矿之前我们必须创建至少一个账户,并将其设为ether base账户,这样矿工挖矿所得的以太币将自动存入我们设置的账户。
因为部署合约需要消耗以太币,这里在私链上通过挖矿获得以太币。

创建账户(账户是一对密钥)

personal.newAccount(“your account passwd”)

输出了一个账户地址:

0xad30387c05b527a85f45186c2b8aab5e1af2f227

这个账户的私钥文件就存储在$datadir/keystore文件夹下。

6、将这个账户设置为矿工etherbase

miner.setEtherbase(eth.accounts[0])  

设置之后,一旦启动挖矿,则挖矿收益就打入这个账户,所以设置之后这个账户也叫coinbase。

以上私链搭建完成。

MetaMask导入账户

MetaMask以太钱包,导入在geth控制台创建的那个账号,然后用这个账户去领养宠物。

首先登录MetaMask,然后点击右上角用户那里->点击导入账户->选择json file类型->选择浏览到keystore下对应账户文件->输入这个账户的密码。

完成上述步骤,就导入了geth新建的账户。

关于MetaMask和账户的关系理解:

MetaMask就是以太钱包。

  • [x] 这个钱包的私钥文件就仅仅存储在你自己的设备上,丢失了就没了。
  • [x] 你的密码就是这个钱包的私钥的加密签名。
  • [x] 钱包地址就是公钥。

账户就是一对公私钥(各为256位的数字),用地址(去掉公钥前12字节,剩余160位,用16进制编码是40个字符)表示。

在MetaMask上建的账户和geth里建的账户,都是典型的外部拥有账户(参见以太坊基础概念专题);

你也可以根据账户的提示词、私钥文件导入其他账户到同一钱包(注意导入的账户要和选择的链网络<公链、私链、测试链等>匹配,也就是该链里先有此账户才能导入,否则只能先创建,可以在钱包界面上创建也可以在geth里用命令创建)。

项目开发

这里用truffle+私链的方式演示企业级项目开发。

项目源码公布在:
https://github.com/m3shine/et...

创建项目

项目所需工具、概念和项目结构描述参见我的另一篇专栏文章:
https://segmentfault.com/a/11...

此项目包含以下功能

  • [x] 领养宠物(仅展示)
  • [x] 发行币(token)

领养宠物

发行币(token)

发行总量为20亿的傻币,代号SB。

首先需要一个合约,其次明确创建合约需要消耗的是gas(以以太币支付),而不是消耗SB。

基于以太坊的币(token)要和以太币区分开。

通过truffle向以太坊私链部署合约

1、在用truffle向私链部署合约前,需要解锁账户。而一个账户被创建时以太坊默认是将其锁住的。

解锁账户

personal.unlockAccount(eth.accounts[0], "you account passwd", 15000)

第三个参数是解锁时间——单位秒。

这里的accounts[0]就是我们搭建私链的时候创建的第一个账户。

2、确保以太坊私链启动中,并有矿工在挖矿(出块)

查看是否有pending的交易,应该没有,有的话会阻塞交易。

txpool.status
miner.start()

3、部署智能合约

在移植之前,

  • [ ] 首先需要有一个账户并设为矿工地址(默认第一个账户就是矿工地址);
  • [ ] 其次需要解锁账户;
  • [ ] 再次需要账户里有钱(eth);
  • [ ] 最后需要有矿工在出块(挖矿)才能完成移植。

cd到truffle工程目录下,执行:

truffle migrate --reset --network development

--network development是根据truffle.js文件里定义的网络使用的:

networks: {development: {host: "127.0.0.1",port: 8545,network_id: "10" // 这里的id必须与创世区块genesis里的chainId一样。}}

--reset

使用reset可以重新执行所有(默认只执行新增而未执行的)migration脚本,但在真实网络里这样做不切实际,因为每次执行都需要消耗gas。\
在区块链中,每个部署都是一个交易,每个交易都是不可逆的。这种架构背后的全部理念是允许我们添加/升级合约并仅重新部署受影响的合同。\
想象一下我们已经升级了一个合约如TokenSB.sol,要怎样部署这个合约而不重新部署其他合约?我们就需要新建一个部署脚本,放在migrations目录下,再执行

truffle migrate

这时将从这个最新的部署脚本开始执行。

看一下移植的输出:

Compiling ./contracts/TokenSB.sol...
Writing artifacts to ./build/contractsUsing network 'development'.Running migration: 1_initial_migration.jsReplacing Migrations...... 0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714Migrations: 0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c
Saving successful migration to network...... 0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6
Saving artifacts...
Running migration: 2_deploy_contract.jsReplacing TokenSB...... 0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057TokenSB: 0xb90598a717180f21a13432d5cc7f1823267c9a95
Saving successful migration to network...... 0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d
Saving artifacts...

这是发生了4笔交易,其中两笔是“合约创建”交易,创建了2个合约(对应生成2个合约账户),另外两笔交易是通过矿工账户支付gas给Migration合约账户来改变它的状态,具体改变了什么状态?在Migraion.sol里的setCompleted函数用来更新部署次数,每执行一个migrate脚本次数加1,改变的这个状态就是最新的部署次数!

upgraded.setCompleted(last_completed_migration);

4笔交易:\
0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714\
0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6\
0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057\
0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d

2个合约账户:\
0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c\
0xb90598a717180f21a13432d5cc7f1823267c9a95

geth日志里对应打印出:

INFO [04-09|16:47:03] Submitted contract creation              fullhash=0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714 contract=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:03] Commit new mining work                   number=11 txs=1 uncles=0 elapsed=2.004s
INFO [04-09|16:47:04] Successfully sealed new block            number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:04] ? block reached canonical chain          number=6  hash=76cc1a…87326d
INFO [04-09|16:47:04] ? mined potential block                  number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:04] Commit new mining work                   number=12 txs=0 uncles=0 elapsed=107.73µs
INFO [04-09|16:47:04] Submitted transaction                    fullhash=0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6 recipient=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:04] Successfully sealed new block            number=12 hash=e3408a…076693
INFO [04-09|16:47:04] ? block reached canonical chain          number=7  hash=5ce86f…e788a4
INFO [04-09|16:47:04] ? mined potential block                  number=12 hash=e3408a…076693
INFO [04-09|16:47:04] Commit new mining work                   number=13 txs=1 uncles=0 elapsed=323.85µs
INFO [04-09|16:47:05] Successfully sealed new block            number=13 hash=c7d419…3bb02a
INFO [04-09|16:47:05] ? block reached canonical chain          number=8  hash=043c14…6b2ee9
INFO [04-09|16:47:05] ? mined potential block                  number=13 hash=c7d419…3bb02a
INFO [04-09|16:47:05] Commit new mining work                   number=14 txs=0 uncles=0 elapsed=179.885µs
INFO [04-09|16:47:05] Successfully sealed new block            number=14 hash=940098…434280
INFO [04-09|16:47:05] Mining too far in the future             wait=2s
INFO [04-09|16:47:05] ? block reached canonical chain          number=9  hash=09c495…d093d3
INFO [04-09|16:47:05] ? mined potential block                  number=14 hash=940098…434280
INFO [04-09|16:47:05] Submitted contract creation              fullhash=0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057 contract=0xb90598a717180F21a13432d5Cc7F1823267c9a95
INFO [04-09|16:47:07] Commit new mining work                   number=15 txs=1 uncles=0 elapsed=2.005s
INFO [04-09|16:47:08] Successfully sealed new block            number=15 hash=fea615…3d68a2
INFO [04-09|16:47:08] ? block reached canonical chain          number=10 hash=f93cfa…2ed290
INFO [04-09|16:47:08] ? mined potential block                  number=15 hash=fea615…3d68a2
INFO [04-09|16:47:08] Commit new mining work                   number=16 txs=0 uncles=0 elapsed=177.032µs
INFO [04-09|16:47:08] Submitted transaction                    fullhash=0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d recipient=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:08] Successfully sealed new block            number=16 hash=cfb2b3…b8a7fe
INFO [04-09|16:47:08] ? block reached canonical chain          number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:08] ? mined potential block                  number=16 hash=cfb2b3…b8a7fe
INFO [04-09|16:47:08] Commit new mining work                   number=17 txs=1 uncles=0 elapsed=290.833µs
INFO [04-09|16:47:09] Successfully sealed new block            number=17 hash=159ff9…f3508d

可知:

有交易的区块分别是:
11、13、15、17

> eth.getBlock(11)
{difficulty: 131712,extraData: "0xd883010800846765746887676f312e392e338664617277696e",gasLimit: 4249054591,gasUsed: 269607,hash: "0xfd0e4e6be5425ce319155cfcbe793f2e6d3d52b2d23fd07f3ecfd94a363955ff",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",mixHash: "0x49a4b5f7caec56999e58755a60227433f29c5c58b0076432d3d62345151de06c",nonce: "0x6a24f90831c7d1f1",number: 11,parentHash: "0xf93cfaec78ecff5cad537060110ec2125950afd420b6ba126eccb1c8812ed290",receiptsRoot: "0xa12b62901dd69f911d94598790f5cd56cd691ccebca50198b50ab64d8a6ebf5b",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 1453,stateRoot: "0x89cd5db1f0ca7692e47401e957f4dce8ee9e8aaac0a4354493029a9134573aaa",timestamp: 1523263623,totalDifficulty: 1576384,transactions: ["0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714"],transactionsRoot: "0xe2a4c28a0c2d74022067bb9aec2a0d3c558c12c415032ab1943ec6ad8d991e06",uncles: []
}> eth.getBlock(13)
{difficulty: 131840,extraData: "0xd883010800846765746887676f312e392e338664617277696e",gasLimit: 4240760105,gasUsed: 41981,hash: "0xc7d419560c21a331d5e5e61a086c49932d4f45f4404208e40fed4af1123bb02a",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",mixHash: "0xf8a970b3d32b998083dd3c39e8ccc7b08a31a4b8c784f707981ea89b266038fb",nonce: "0x4adb44428e6e46a5",number: 13,parentHash: "0xe3408acd7715d948e601463d3cb7ce2e233ca3822015a24a2ba2dfe35f076693",receiptsRoot: "0x1ced6b6f323a6d3c8854348bf48831c1279e67ba5a942d354b4f865e42da0eb6",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 679,stateRoot: "0x11c52848f9358e3c440a29cd704bcee363693a2582680688e21ee2b334aa9c4d",timestamp: 1523263625,totalDifficulty: 1840000,transactions: ["0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6"],transactionsRoot: "0x99f487f4989fda3411587062d0c0d8b77c8384786ed8611c600f8a8adc878d22",uncles: []
}> eth.getBlock(15)
{difficulty: 131968,extraData: "0xd883010800846765746887676f312e392e338664617277696e",gasLimit: 4232481478,gasUsed: 1155362,hash: "0xfea615d7f14b9eea5557ee7db714865a662b8f2638303dad31a2b01d1c3d68a2",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",mixHash: "0x6d445e0680455e1b426eac12486bd44d48885d47db9fcf9ef3e37d1cfdce6aa5",nonce: "0x343cce18fe3e47df",number: 15,parentHash: "0x940098cd10e8ffd179b11c719896aed6efd518c89bfec83917f9d78faa434280",receiptsRoot: "0xe0619e0df84cf66deb0332cdd5b636c360ad4c6b2efa6960206dd16e67ac64fd",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 4929,stateRoot: "0xb3ede09e46d4e16d7ac1693fa6ccc7f81d6a5a37160f39b2e6e29dee76ed4175",timestamp: 1523263627,totalDifficulty: 2103872,transactions: ["0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057"],transactionsRoot: "0xec03b0be1484e3cac495ef585ac0e9fd63e662ef466bdc717e0e8c1acdb8fbfb",uncles: []
}> eth.getBlock(17)
{difficulty: 132096,extraData: "0xd883010800846765746887676f312e392e338664617277696e",gasLimit: 4224220643,gasUsed: 26981,hash: "0x159ff93dc61a32249f7f6c82fd0db65b8b45e33f416a29a047b2368edaf3508d",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",mixHash: "0xf5eda18e9417084bc0e8dcee5a1d05d9c5ef37108427d8265ac4000b7efc9261",nonce: "0x0c5e1f26c990f4d2",number: 17,parentHash: "0xcfb2b3cdda47aa0e7cb785f008613424402709ab6bdf759ea644a85af6b8a7fe",receiptsRoot: "0xcabd0eff6a0d339c032b7f9cb5a9f8211ab94c1626c698eff51930d07e103a57",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 679,stateRoot: "0xa7c3e91886e55c296c8f0f3566bdf7fe37c09ec3e1a9a74c7583a76a18442d9e",timestamp: 1523263629,totalDifficulty: 2368000,transactions: ["0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d"],transactionsRoot: "0x37ae7f0819cc599fc1edd798dccc5298d7aad92314a1e3fce4703e4516ffc9e2",uncles: []
}

4笔交易分别是:

> eth.getTransaction('0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714')
{blockHash: "0xfd0e4e6be5425ce319155cfcbe793f2e6d3d52b2d23fd07f3ecfd94a363955ff",blockNumber: 11,from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",gas: 6721975,gasPrice: 100000000000,hash: "0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714",input: "0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102db8061005e6000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610224565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc61022a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610220578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b6102c65a03f1151561021c57600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102ac57806001819055505b505600a165627a7a723058200d2898098cb3b0615d05013d7ff7cf6e54eaff6b98e66e9e5a864778b9c6c69d0029",nonce: 0,r: "0xd9bfae2f413b63cb615d423773f6a48c2898f695be6e13060f9fe43af6a33231",s: "0x1a3c02f7f90dc7acd2a75f2ff7018fcb92981815fa9b590c9b9e9bc142ccb5b5",to: null,transactionIndex: 0,v: "0x38",value: 0
}> eth.getTransaction('0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6')
{blockHash: "0xc7d419560c21a331d5e5e61a086c49932d4f45f4404208e40fed4af1123bb02a",blockNumber: 13,from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",gas: 6721975,gasPrice: 100000000000,hash: "0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6",input: "0xfdacd5760000000000000000000000000000000000000000000000000000000000000001",nonce: 1,r: "0xe8666b647d772228051922ccd2bbec8d6fb1622716e5484e1a500d9b9de98120",s: "0x35fbdb3a0a700f7a1cdf793ab5a6643131660dc64bc8d867a267fdd6cf8e1317",to: "0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c",transactionIndex: 0,v: "0x38",value: 0
}> eth.getTransaction('0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057')
{blockHash: "0xfea615d7f14b9eea5557ee7db714865a662b8f2638303dad31a2b01d1c3d68a2",blockNumber: 15,from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",gas: 6721975,gasPrice: 100000000000,hash: "0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057",input: "0x60606040526012600260006101000a81548160ff021916908360ff160217905550341561002b57600080fd5b604051610fed380380610fed83398101604052808051906020019091908051820191906020018051820191905050600260009054906101000a900460ff1660ff16600a0a8302600381905550600354600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600090805190602001906100d39291906100f3565b5080600190805190602001906100ea9291906100f3565b50505050610198565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061013457805160ff1916838001178555610162565b82800160010185558215610162579182015b82811115610161578251825591602001919060010190610146565b5b50905061016f9190610173565b5090565b61019591905b80821115610191576000816000905550600101610179565b5090565b90565b610e46806101a76000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c5578063313ce5671461023e57806342966c681461026d57806370a08231146102a857806379cc6790146102f557806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e1461041f575b600080fd5b34156100bf57600080fd5b6100c761048b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610529565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af6105b6565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105bc565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b6102516106e9565b604051808260ff1660ff16815260200191505060405180910390f35b341561027857600080fd5b61028e60048080359060200190919050506106fc565b604051808215151515815260200191505060405180910390f35b34156102b357600080fd5b6102df600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610800565b6040518082815260200191505060405180910390f35b341561030057600080fd5b610335600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610818565b604051808215151515815260200191505060405180910390f35b341561035a57600080fd5b610362610a32565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610ad0565b005b341561042a57600080fd5b610475600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610adf565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105215780601f106104f657610100808354040283529160200191610521565b820191906000526020600020905b81548152906001019060200180831161050457829003601f168201915b505050505081565b600081600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60035481565b6000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561064957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506106de848484610b04565b600190509392505050565b600260009054906101000a900460ff1681565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561074c57600080fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b60046020528060005260406000206000915090505481565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561086857600080fd5b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111515156108f357600080fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ac85780601f10610a9d57610100808354040283529160200191610ac8565b820191906000526020600020905b815481529060010190602001808311610aab57829003601f168201915b505050505081565b610adb338383610b04565b5050565b6005602052816000526040600020602052806000526040600020600091509150505481565b6000808373ffffffffffffffffffffffffffffffffffffffff1614151515610b2b57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610b7957600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401111515610c0757600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401905081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a380600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401141515610e1457fe5b505050505600a165627a7a7230582058fcacc120960c2cf4be32f0b37a1e0be3601914de2acfb57bad06edc4e9f1ed00290000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000006e582bbe5b881000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025342000000000000000000000000000000000000000000000000000000000000",nonce: 2,r: "0xbd3c155041f1385edb2b6321083c43421ceb2ed7129c52ac72693529852ae59f",s: "0x73a4c275d28a8c87e710bdd571865054ada56e78c5c65541979da4cc619a097d",to: null,transactionIndex: 0,v: "0x37",value: 0
}> eth.getTransaction('0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d')
{blockHash: "0x159ff93dc61a32249f7f6c82fd0db65b8b45e33f416a29a047b2368edaf3508d",blockNumber: 17,from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",gas: 6721975,gasPrice: 100000000000,hash: "0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d",input: "0xfdacd5760000000000000000000000000000000000000000000000000000000000000002",nonce: 3,r: "0x97fbfded3651e150969343f31ac081bc08278c3a2d2c76f70881278f7334b8a0",s: "0x2d9a40b70557928d2abe0256f53ce97068db18c4198923e78e550e5f6f1a282e",to: "0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c",transactionIndex: 0,v: "0x38",value: 0
}

to为空的两笔交易是2个合约的实际部署。\
to不为空的两笔交易是更改Migration合约的状态,是消息调用类型的交易。

部署完成后,现在这个矿工账户0xad30387c05b527a85f45186c2b8aab5e1af2f227里就有2亿亿SB(这里单位是wei,注意token也是使用的wei,可以转换成ether单位展示)了。为什么是矿工账户?因为是TokenSB构造函数里这句话决定的:

balanceOf[msg.sender] = totalSupply;  

构造函数的创建是由矿工0xad30387c05b527a85f45186c2b8aab5e1af2f227完成的,即msg.sender当时是矿工,这个构造函数只执行一次。

交易在黄皮书里的定义就是一个状态转换函数,我们分析这个状态转换函数究竟做了些什么事情。

1、创建一个外部账户\
personal.newAccount('passwd'),即生成一个公钥私钥对。

2、“合约创建”

创建一个合约账户时使用了很多内在参数:(先不解释了,以后再说)\

sender (s), \
original transactor (o), \
available gas (g), \
gas price (p), \
endowment (v) \
i\
stack (e)

a ≡ B96..255(KEC(RLP((s, σ[s]n − 1))))

合约账户的地址是:仅由创建合约的sender和其nonce构成的RLP编码的Keccak Hash的右起160位。这里的96…255是说KEC的hash值会在这个位数范围内,也即地址位数。\
而之所以是nonce-1,是因为公式里用的是sender当前的nonce,而创建合约账户时的nonce一定是小1的。

运行项目

在truffle工程目录下执行

npm run dev

常见问题

领养的时候实际是发送交易,调用了eth_sendRawTransaction api。

Error: [ethjs-rpc] rpc error with payload {"id":7299823052815,"jsonrpc":"2.0","params":["0xf88605843b9aca0082f65a94c069c6502457c854f669746861712141ad81414080a48588b2c5000000000000000000000000000000000000000000000000000000000000000025a05ca4a04ef943c9383776ee4c39d6479ac739d470571dcfc842ef0bcfe3ec5f999f6b8966b830b7f0e03cd15c3dd660cd19fe5550196084519eed5a20c8880743"],"method":"eth_sendRawTransaction"} Error: invalid sender

解决答案是:truffle.js的network_id和genesis的chainId需要一样。

Solidity

IDE语法支持

  • 在IDE里安装soldity插件用于支持语法高亮。IDEA系列IDE直接搜索solidity安装。
  • Atom的插件安装,在Atom启动的情况下,使用命令安装:

    apm install linter
    apm install linter-solidity

编译器安装方式

  • 在本地安装solcjs这个solidity编译器(这种安装方式最简单)

    可以在js里引用模块、写编译方法,执行js对solidity编译。

    cnpm i -g solc

    也可以在控制台编译.sol文件,使用

    solcjs --abi xxx.sol
  • 或者mac上安装本地编译器(这种安装方式最费劲),编译器集成在solidity包里。

    brew update
    brew upgrade
    brew tap ethereum/ethereum
    brew install solidity
    brew linkapps solidity

    设好solidity/bin环境变量后,控制台编译使用

    solc --abi -o solcoutput xxx.sol

注意:geth1.6.0之后就不再集成solc了,所以geth控制台里已无法再编译合约。

web3

web3是一个js库,在js应用中可以通过以太坊节点提供的http RPC接口与以太坊节点交互。

https://github.com/ethereum/w...

geth --rpc

这个geth命令就是启用了HTTP JSON-RPC(go版节点默认rpc端口是8545,还可以用--rpccorsdomain设置跨域)。

下面是geth console里启用rpc的方法:

admin.startRPC(addr, port)

下面这些方法都有一个额外的默认参数block

  • eth_getBalance
  • eth_getCode
  • eth_getTransactionCount
  • eth_getStorageAt
  • eth_call

参数block可以取值{

  • HEX String - an integer block number
  • String "earliest" for the earliest/genesis block
  • String "latest" - for the latest mined block
  • String "pending" - for the pending state/transactions

}

web3接口可以批量请求,批量请求并不会更快,而主要是确保请求的串行处理。

项目是通过web3.js与以太坊进行交互的,比如通过web3对象获取当前玩家的以太坊账户并进行交易。

 $.getJSON('TokenSB.json', function (data) {var TokenArtifact = data;App.contracts.Token = TruffleContract(TokenArtifact);App.contracts.Token.setProvider(App.web3Provider);})

web3初始化

// 这里是判断否已存在web3,比如,如果是用户登录MetaMask连接到本网络,则web3是MetaMask的web3。
// MetaMask创建的账户由MetaMask维护,而导入的账户则每次登录MetaMask都需要重新导入。
// 否则就创建一个web3,这就可能需要自行实现钱包让用户登录了。
if (typeof web3 !== 'undefined') {App.web3Provider = web3.currentProvider;
} else {App.web3Provider = new web3.providers.HttpProvider('http://localhost:8545');
}

LevelDB

LevelDB只能被一个进程占用,当私链启用的时候,其他进程是不能访问的,比如LevelDB的某种客户端。

可以用以下工具访问本地LevelDB:
https://github.com/liderman/l...
前提是结束私链运行。

以太坊的数据库通过源码可知:
LevelDB实例加载的是$datadir/geth/chaindata这个目录。

以太坊私链搭建、truffle项目开发相关推荐

  1. 以太坊私链搭建(二)——genesis.json字段解读

    genesis.json文件用于配置生成以太坊私链网络的创世区块,当我们需要去创建一个创世区块时,我们可以通过修改genesis.json文件内的初始参数将这些数据写入创世区块.下面是以太坊官方文档给 ...

  2. 以太坊私链搭建(Windows+geth)

    文章目录 1. Geth下载与安装 1.1 Geth下载 1.2 Geth安装 2. 搭建私有链 2.1 创世区块配置 2.2 创世区块初始化 3 启动私链节点 / 进入geth控制台 4 创建账户 ...

  3. 如何搭建socks5和ss节点_以太坊区块链搭建与使用(三)-联盟链

    首先对以下概念说明下: 一.以太坊大家都知道比特币使用的技术是区块链技术,比特币也是区块链技术的代表. 即比特币=区块链1.0随着区块链技术的发展以太坊也诞生了,也就是我们说的 区块链2.0.为什么说 ...

  4. 以太坊区块链_以太坊区块链搭建与使用(一)-私有链

    步骤 一.下载go语言,并配置环境变量 //以太坊源代码依赖的编译与运行环境 二.通过git clone以太坊源码(go-ethereum),并编译 一.go安装 step1:下载 官方(一般打不开) ...

  5. Windows环境下搭建基于PoA共识算法的多节点以太坊私链

    本文阐述在一台windows电脑上,搭建基于PoA共识算法的以太坊私链(3个挖矿节点),步骤如下: (1)生成3个矿工账号 假设3个节点的数据目录分别是: 节点1 e:\work\test\1_poa ...

  6. 搭建以太坊私链创建新账户时遇到“personal is not defined“错误

    在完成以太坊私链的初始化后,我尝试创建一个新用户却遇到如下报错. 我的配置如下: ubuntu-18.04.6-desktop-amd64.ios geth-alltools-linux-amd64- ...

  7. solidity payable_以太坊区块链搭建与使用(五)-智能合约Solidity

    一.智能合约Solidity开发工具 1.remix-ide http://remix.ethereum.org/ 在线版本,也可以去github下载安装到本地.开发.编译.发布.执行.测试 2.re ...

  8. 【问题】以太坊私链连接钱包报错解决汇总

    以太坊私链连接钱包报错解决汇总 关键词 虚拟机 MetaMask 私有链 rpc 以太坊 问题简述 区块链私链搭建完成之后,连接虚拟机上的私链与MetaMask钱包过程调试问题解决,主要包括 以太坊命 ...

  9. 以太坊 私有链搭建 Geth+Mist钱包

    近期在区块链的热潮推动下,我开始研究区块链技术,尤其是智能合约.可编程式的智能合约龙头老大非以太坊莫属了,其他的合约平台如 hyperledger,EOS 相对来说没以太坊成熟,以后陆续在研究.好了, ...

最新文章

  1. 基础学习总结(四)--SQLite
  2. Vue打包后部署使用Nginx
  3. 记一次CTF实验吧的代码审计
  4. Linux 0.11 实验环境搭建与调试
  5. 找零兑换(递归解法)
  6. 如何在 JavaScript 面试中过五关斩六将?
  7. linux项目实验ppt下载,实验一Linux系统的使用.ppt
  8. 强大的诺顿扼杀了alexa工具条
  9. Java多线程及锁相关面试题
  10. 从IT时代到DT时代
  11. 【网络与信息安全】 2019年-中国计算机学会推荐国际学术会议和期刊目录(三)
  12. Python之Selenium模拟浏览器
  13. POJ-1436___Horizontally Visible Segments —— 线段树
  14. 在浏览器中聊天(msn.jabber or gtalk,yahoo,aol,icq,meebo)
  15. 垃圾小白羊leetcode刷题记录1
  16. 产品生命周期,鸿沟理论和CNCF项目孵化
  17. 广东惠州港口吞吐量稳中有升
  18. 年薪超1400万美元,库克即将卸任,谁接掌苹果CEO?
  19. IBIS建模——第2部分:为何以及如何创建您自己的IBIS模型
  20. NMAP——如何使用

热门文章

  1. 采用Android的MediaPlayer+SurfaceView设计视频播放器
  2. 带你看懂LayoutInflater中inflate方法
  3. 第四周项目二-太乐了
  4. python怎么定义空矩阵_python 空矩阵
  5. PHP学习笔记-PHP语言基础3
  6. Kafka Sender线程如何发送数据
  7. 数据库主键设计之思考
  8. zbb20170824 oracle expdp/impdp 导入导出数据
  9. 提高工作效率-shell操作快捷键
  10. 《Ajax实战》三部曲之“王者归来”