-
编译问题
1.6版本之前和1.6版本及之后,最大的差异就是就是得到abi和bytecode的方式不同。之前的直接集合geth的环境中。之后的需要单独提出来进行处理。下面介绍的就是1.6版本后。abi和bytecode的获取。
- 第一种方式。在编译网站进行编译,然后选中compile(编译按钮)->点击Details(详情按钮)->弹出的界面中下滑找到WEB3DEPLOY,得到内容。或者下滑找到BYTECODE,点击复制,然后在数据前加0x,找到INTERFACE - ABI,然后这就是abi。
// web3.eth.contract()中括号中的内容就是abi // abi = [{"constant":true,"inputs":[],"name":"count","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCount","outputs":[{"name":"a","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] var browser_ballot_sol_simplestorageContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"count","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCount","outputs":[{"name":"a","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]); // 下面中data对应的内容就是bytecode // bytecode = '0x60606040526007600055341561001457600080fd5b60e9806100226000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14604e578063a87d942c146074575b600080fd5b3415605857600080fd5b605e609a565b6040518082815260200191505060405180910390f35b3415607e57600080fd5b608460a0565b6040518082815260200191505060405180910390f35b60005481565b600060ab60005460b0565b905090565b60006007820290509190505600a165627a7a72305820ce3994eccf8989c24603717c6996c128cbde4dff903c7b3f6cd101c3ac6c092c0029' var browser_ballot_sol_simplestorage = browser_ballot_sol_simplestorageContract.new( { from: web3.eth.accounts[0], data: '0x60606040526007600055341561001457600080fd5b60e9806100226000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14604e578063a87d942c146074575b600080fd5b3415605857600080fd5b605e609a565b6040518082815260200191505060405180910390f35b3415607e57600080fd5b608460a0565b6040518082815260200191505060405180910390f35b60005481565b600060ab60005460b0565b905090565b60006007820290509190505600a165627a7a72305820ce3994eccf8989c24603717c6996c128cbde4dff903c7b3f6cd101c3ac6c092c0029', gas: '4700000' }, function (e, contract){ console.log(e, contract); if (typeof contract.address !== 'undefined') { console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash); } })
- 第二种方式用安装Solidity,然后命令行进行编译
soliditySource.sol就是把示例代码保存的一个文件,后缀是.sol // 生成bytecode,输出的内容最前加上 0x,也就是0和x solc --bin soliditySource.sol // 生成abi solc --abi soliditySource.sol
- Solidity代码示例
pragma solidity ^0.4.0; contract SimpleStorage { // 一个公开的变量 uint256 public count = 7; // 一个私有的方法 function multiply(uint256 a) internal pure returns (uint256 b) { return a * 7; } // 一个公开的方法 function getCount() public constant returns (uint256 a) { return multiply(count); } }
- 第一种方式。在编译网站进行编译,然后选中compile(编译按钮)->点击Details(详情按钮)->弹出的界面中下滑找到WEB3DEPLOY,得到内容。或者下滑找到BYTECODE,点击复制,然后在数据前加0x,找到INTERFACE - ABI,然后这就是abi。
-
部署
- 进入geth环境。参考本地以太坊调用的测试
- 进入配置如下:
// 进入geth环境 localhost:ethereum zsk$ ./start.sh 00 // 确保你的用户存在且你本身有币(也就是你挖矿到一定数量的以太币)。不然如果没有币你在部署的时候会报错,具体错误不表 // 用user变量接受用户地址 > user = eth.accounts[0] // abi变量接受abi真实数据 > abi = [{"constant":true,"inputs":[],"name":"count","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCount","outputs":[{"name":"a","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] // bytecode接受真实的bytecode数据 bytecode = '0x60606040526007600055341561001457600080fd5b60e9806100226000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14604e578063a87d942c146074575b600080fd5b3415605857600080fd5b605e609a565b6040518082815260200191505060405180910390f35b3415607e57600080fd5b608460a0565b6040518082815260200191505060405180910390f35b60005481565b600060ab60005460b0565b905090565b60006007820290509190505600a165627a7a72305820ce3994eccf8989c24603717c6996c128cbde4dff903c7b3f6cd101c3ac6c092c0029' > contract = web3.eth.contract(abi) // 先解锁用户 abc123是创建用户的密码 > personal.unlockAccount(user, 'abc123') // 发布合约 user就是用户地址,data就是bytecode字节,gas就是交易消耗的币,其他的暂时可以不管 > contractObject = contract.new({from: user,data:bytecode,gas: 4700000}, function (e, contract){console.log(e, contract);if (typeof contract.address !== 'undefined') {console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);}}) // 此时代表有一笔交易待确定 > txpool.status { pending: 1, queued: 0 } // 查看待确认交易的详细内容 from数据项就是我们发送交易的地址,input就是合约编译完成的字节码,这些内容均与我们之前的设定相同。而且,我们可以看到新的交易创建在第92区块中 > eth.getBlock("pending",true).transactions [{ blockHash: "0x619c95ad722b88fe301d59ef962b4fee52ab75184520ebe85f780230f6bed96e", blockNumber: 92, from: "0x4079a3f5ffeeb7a84a4a582e9fc5f25579c3bba0", gas: 4700000, gasPrice: 18000000000, hash: "0x6b02ebd337e7e48f858c387c24f1f1dbc2ead86027dd36b95a319fde4c1004e2", input: "0x60606040526007600055341561001457600080fd5b60e9806100226000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd14604e578063a87d942c146074575b600080fd5b3415605857600080fd5b605e609a565b6040518082815260200191505060405180910390f35b3415607e57600080fd5b608460a0565b6040518082815260200191505060405180910390f35b60005481565b600060ab60005460b0565b905090565b60006007820290509190505600a165627a7a72305820ce3994eccf8989c24603717c6996c128cbde4dff903c7b3f6cd101c3ac6c092c0029", nonce: 10, r: "0x6db55d786e54d2f99befc78a28623548dac27e8b9b20b267a8681f9f79cec35a", s: "0x6ba72c168c000cbc7b8cc3c30eaa50b9afaf86fa90b259bc017042701dbe1090", to: null, transactionIndex: 0, v: "0x42", value: 0 }] // 要进行挖矿,才能得到合约才能得到确认,本地测试网络必须是本节点挖矿,其他的节点挖矿不行。 > miner.start() // 等到出现就代表着合约部署完成 Contract mined! address: 0x59e9808ff1ca975193801a96552e4883ebbcb26f transactionHash: 0x95ac41354a8bf5907a2c68365331b3adad2a9313691b41b103b74c20aa047c58 // 查看第92号区块的信息 发现hash值与transactions中的值保持一致,说明数据已经写进入块了 > eth.getBlock(92) { difficulty: 189762, extraData: "0xd883010702846765746887676f312e392e328664617277696e", gasLimit: 3925747580, gasUsed: 134976, hash: "0xb1b0e57bc1ecb95822945c4360ebd937f7d78e5e41610ad6d5fb82bcfb30378c", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x4079a3f5ffeeb7a84a4a582e9fc5f25579c3bba0", mixHash: "0x1b3e18f44b4e2c2aca124811bd2affe4d9295541016191c9083829e8d5506d34", nonce: "0x5d02db68ddcd3c03", number: 92, parentHash: "0xe035d79196ffc1864b30bd47685860132dd12c425c3d268cd6604d23afdb2061", receiptsRoot: "0x57fa38ab7e361c5b9fb23ec518e103ecce8e219303b65a5a9f871d1b37656bcb", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 895, stateRoot: "0x6c6daa8481c9293e7ff9a701c6f957b719b3f43f1bccc644067e1a4b9a84c3b7", timestamp: 1510226672, totalDifficulty: 21191635, transactions: ["0x6b02ebd337e7e48f858c387c24f1f1dbc2ead86027dd36b95a319fde4c1004e2"], transactionsRoot: "0x1a5035077c1cfdf8b10900b7847df60138968857c19c16d11383a7a4977da158", uncles: [] } // 获得合约的实例,输出的最下面count就是我们公开的变量,getCount就是我们公开的方法 > myContractInstance = contract.at(contractObject.address) { abi: [{ constant: true, inputs: [], name: "count", outputs: [{...}], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "getCount", outputs: [{...}], payable: false, stateMutability: "view", type: "function" }], address: "0x2f58bd410dc3494cf801aeb5907c6cd154360ad2", transactionHash: null, allEvents: function(), count: function(), getCount: function() } // 调用变量输出变量值 > myContractInstance.count.call() 7 // 调用方法,输出返回的值 > myContractInstance.getCount.call() 49
参考资料
编译器官方代码solidity
solidity官方开发文档
浏览器端的编译网站
Ethereum 智能合约实战
geth1.6部署智能合约
Ethereum 智能合约实战
ethereum-learn学习笔记
stackexchange: How to compile Solidity contracts with Geth v1.6?
直接在1.6之后使用之前的代码执行会提醒eth_compileSolidity,官方讨论
老的版本介绍基础知识可以参考学习:以太坊智能合约编程之菜鸟教程
深入解析调用合约的三种方法
网友评论