- 第 1 章 区块链
- 1.2. 什么是智能合约?
- 1.3. 我们应该怎么做?
- 1.4. 如何学习区块链
- 1.5. 币圈与链圈
- 1.6. 区块链能做什么
- 1.7. 区块链不能解决的问题
- 1.8. 理解去中心化
- 1.9. 理解不可撰改
- 1.10. 理解分布式记账
- 1.11. 安全问题
- 1.12. 区块链落地面临的问题
- 1.13. 区块链未来
- 1.14. 区块链的六层模型
- 1.15. 共识机制
- 1.16. SHA-256
- 1.17. Base58编码
- 1.18. Merkle
- 1.19. BIP39协议:使用助记词生成确定性钱包
- 1.20. Ethereum vs Hypterledger Fabic vs EOS 对比
- 1.21. 区块链探索
- 第 2 章 以太坊
- 第 3 章 以太坊私链入门
- 第 4 章 以太坊网络
- 第 5 章 geth v1.8.16 命令详解
- 第 6 章 Wallet
- 第 7 章 Token
- 第 8 章 智能合约语言 Solidity v0.5.0
- 8.2. solc 命令
- 8.3. 智能合约入门演示
- 8.4. Helloworld Example
- 8.5. 数据类型
- 8.6. 单位
- 8.7. 变量
- 8.8. 函数
- 8.9. 事件
- 8.10. 面向对象编程
- 8.11. 合约调用
- 8.12. 合约接收 ETH
- 8.13. 合约中实例化一个接口
- 8.14. 合约中实例化另一个合约
- 8.15. Solidity 安全问题
- 8.16. solidity example
- 8.17. Zeppelin Solidity - OpenZeppelin is a library for writing secure Smart Contracts on Ethereum.
- 第 9 章 Truffle v4.1.8 开发框架
- 第 10 章 web3.js - 1.0.0
- 第 11 章 web3j v3.4.0 - Jave Client
- 11.2. 启动以太坊
- 11.3. Maven pom.xml 文件
- 11.4. Java 与 Solidity 数据类型映射关系
- 11.5. 常量
- 11.6. 连接到服务器获取版本号
- 11.7. 获得以太坊状态信息
- 11.8. 单位转换
- 11.9. 账号管理
- 11.10. Credentials
- 11.11. 交易
- 11.12. 钱包
- 11.13. 智能合约
- 11.14. ERC20合约
- 11.15. Infura
- 11.16. 助记词
- 11.17. 过滤器 (Filter)
- 11.18. Subscription
- 11.19. 解锁账号
- 11.20. IBAN (International Bank Account Number)
- 11.21. Springboot with Ethereum (web3j)
- 第 12 章 web3.py - A python interface for interacting with the Ethereum blockchain and ecosystem.
- 第 14 章 Ethereum Developer APIs
- 第 15 章 infura
- 第 16 章 以太坊案例
- 第 17 章 FAQ
- 17.3. Error: authentication needed: password or unlock
- 17.4. 新增节点后不生效
- 17.5. Unhandled rejection Error: Returned error: The method personal_unlockAccount does not exist/is not available
- 17.6. Error: exceeds block gas limit
- 17.7. Migrations.sol:11:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(…) { … }" instead.
- 17.8. Exception in thread "main" rx.exceptions.OnErrorNotImplementedException: Invalid response received: okhttp3.internal.http.RealResponseBody@6c25e6c4
- 17.9. 旧版本 Remix(browser-solidity) 本地安装
- 第 18 章 Hyperledger Fabric v2.0.0
- 第 19 章 Hyperledger Fabric 运维
- 第 20 章 Chaincode 链码(智能合约)
- 第 21 章 Hyperledger Fabric Client SDK for Node.js
- 第 22 章 fabric-sdk-java
- 第 24 章 已知 Hyperledger 落地案例
- 第 25 章 Fabric Command
- 第 26 章 Fabric FAQ
- 第 27 章 IPFS(InterPlanetary File System,星际文件系统)
- 第 28 章 IPFS 命令
- 第 29 章 IPFS WebUI
- 第 30 章 IPFS 集群配置
- 第 31 章 IPFS API
- 第 32 章 IPFS Faq
- 第 33 章 EOS
- 第 34 章 EOS 安装
- 第 35 章 CLEOS
- 第 36 章 智能合约开发
- 第 37 章 EOS Dapp 开发
- 第 38 章 FAQ
- 第 39 章 BaaS (Blockchain as a Service) 平台
- 第 40 章 BitCoin
- 第 41 章 其他区块链相关
- 附录 1. 附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
10.7. 智能合约
10.7. 智能合约
10.7.1. 部署合约
解锁账号
> personal.unlockAccount(eth.accounts[0], "netkiller",5000) true > miner.stop() true > miner.start(2)
编译只能合约
solc --bin --abi --optimize -o ./output helloworld.sol
var Web3 = require("web3"); var fs = require ('fs'); var web3 = new Web3("http://localhost:8545"); var abi = JSON.parse(fs.readFileSync('output/Netkiller.abi')); var bin = '0x'+fs.readFileSync('output/Netkiller.bin').toString(); var myContract = new web3.eth.Contract(abi, null, { from: '0x5c18a33DF2cc41a1bedDC91133b8422e89f041B7' }); myContract.deploy({ data: bin }).send({ from: '0x5c18a33DF2cc41a1bedDC91133b8422e89f041B7', gas: 1500000, gasPrice: '30000000000000' }).then(function(newContractInstance){ console.log(newContractInstance.options.address) });
10.7.2. 使用最佳手续费创建合约
var fs = require('fs'); var net = require('net'); var Web3 = require("web3"); var fs = require ('fs'); var web3 = new Web3("http://localhost:8545"); var abi = JSON.parse(fs.readFileSync('NetkillerAdvancedToken.abi')); var bin = '0x'+fs.readFileSync('NetkillerAdvancedToken.bin').toString(); var address = '0x22c57F0537414FD95b9f0f08f1E51d8b96F14029'; var myContract = new web3.eth.Contract(abi, null, {from: address}); var options = { data: bin, arguments: [100000000, 'Netkiller Test Coin', 'NTC', 18] }; web3.eth.getGasPrice().then(function(gasPrice){ myContract.deploy(options).estimateGas(function(err, gas){ console.log(gas); web3.eth.personal.unlockAccount(req.body.from, req.body.password).then(function(error){ myContract.deploy(options).send({ from: address, gas: gas, gasPrice: gasPrice }).then(function(newContractInstance){ console.log(newContractInstance.options.address) }); }); }); });
10.7.3. 调用合约
部署智能合约,你可以使用钱包部署,也可以使用Truffer部署,不管你采用什么方式,最终我们需要合约地址。
pragma solidity ^0.4.18; contract MetaCoin { mapping (address => uint) balances; event Transfer(address indexed _from, address indexed _to, uint256 _value); function MetaCoin() public { balances[tx.origin] = 10000; } function sendCoin(address receiver, uint amount) public returns(bool sufficient) { if (balances[msg.sender] < amount) return false; balances[msg.sender] -= amount; balances[receiver] += amount; Transfer(msg.sender, receiver, amount); return true; } function getBalanceInEth(address addr) public view returns(uint){ return convert(getBalance(addr),2); } function getBalance(address addr) public view returns(uint) { return balances[addr]; } function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) { return amount * conversionRate; } }
这里使用 Truffle 部署
neo@MacBook-Pro ~/ethereum/truffle % truffle compile --all Compiling ./contracts/MetaCoin.sol... Writing artifacts to ./build/contracts neo@MacBook-Pro ~/ethereum/truffle % truffle migrate --reset Using network 'development'. Running migration: 5_initial_migration.js Deploying MetaCoin... ... 0x9c006b398733a1d8679cbb00493ca75ff063f51c34521ae67a70523deeebf9c4 MetaCoin: 0xfb88de099e13c3ed21f80a7a1e49f8caecf10df6 Saving successful migration to network... ... 0x755a48ef99e488d7cf8460d718773a5afe73f760fb87697e51c40f3e6086f10b Saving artifacts...
得到合约地址 MetaCoin: 0xfb88de099e13c3ed21f80a7a1e49f8caecf10df6
编译合约获得 abi 接口
neo@MacBook-Pro ~/ethereum/truffle % solc --bin --abi --optimize -o ./output contracts/MetaCoin.sol neo@MacBook-Pro ~/ethereum/truffle % cat output/MetaCoin.abi [{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getBalanceInEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"amount","type":"uint256"},{"name":"conversionRate","type":"uint256"}],"name":"convert","outputs":[{"name":"convertedAmount","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]
var Web3 = require("web3"); // 创建web3对象 var web3 = new Web3("http://localhost:9545"); // 合约ABI var abi = [{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getBalanceInEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"amount","type":"uint256"},{"name":"conversionRate","type":"uint256"}],"name":"convert","outputs":[{"name":"convertedAmount","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]; // 合约地址 var address = "0xfb88de099e13c3ed21f80a7a1e49f8caecf10df6"; var tokenContract = new web3.eth.Contract(abi, address); // 调用函数 tokenContract.methods.getBalance("0x627306090abab3a6e1400e9345bc60c78a8bef57").call(null,function(error,result){ console.log("getBalance "+result); }); tokenContract.methods.getBalanceInEth("0x627306090abab3a6e1400e9345bc60c78a8bef57").call(null,function(error,result){ console.log("getBalanceInEth "+result); }); tokenContract.methods.getBalance("0xf17f52151ebef6c7334fad080c5704d77216b732").call(null,function(error,result){ console.log("getBalance 2 "+result); }); tokenContract.methods.sendCoin("0xf17f52151ebef6c7334fad080c5704d77216b732",387).send({from: '0x627306090abab3a6e1400e9345bc60c78a8bef57'}) .on('transactionHash', function(hash){ }).on('confirmation', function(confirmationNumber, receipt){ }).on('receipt', function(receipt){ // receipt example console.log(receipt); //查询这里可以得到结果 }).on('error', console.error); // If a out of gas error, the second parameter is the receipt.
运行结果
getBalance 10000 getBalanceInEth 20000 getBalance 2 0 { transactionHash: '0x0f7514413865219d70873634c00d1b4746c5faa436283786f5414b483b6d6333', transactionIndex: 0, blockHash: '0x5a7662d14f78b6b4d64b05c0ec1e1e641bd39440467f0476409f4e49c21f287a', blockNumber: 11, gasUsed: 51024, cumulativeGasUsed: 51024, contractAddress: null, status: 1, events: { Transfer: { logIndex: 0, transactionIndex: 0, transactionHash: '0x0f7514413865219d70873634c00d1b4746c5faa436283786f5414b483b6d6333', blockHash: '0x5a7662d14f78b6b4d64b05c0ec1e1e641bd39440467f0476409f4e49c21f287a', blockNumber: 11, address: '0xFB88dE099e13c3ED21F80a7a1E49f8CAEcF10df6', type: 'mined', id: 'log_8b567824', returnValues: [Result], event: 'Transfer', signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', raw: [Object] } } }
再次运行
getBalance 9613 getBalanceInEth 19226 getBalance 2 387 { transactionHash: '0x6d33487d9067494288190f7a64b3118c20560479e01afe8d53e37ca46a6001e4', transactionIndex: 0, blockHash: '0x28f6d416c68dbbd698d1a0b0fdc4ce842694d82318a38ea6395413fd15397642', blockNumber: 12, gasUsed: 36024, cumulativeGasUsed: 36024, contractAddress: null, status: 1, events: { Transfer: { logIndex: 0, transactionIndex: 0, transactionHash: '0x6d33487d9067494288190f7a64b3118c20560479e01afe8d53e37ca46a6001e4', blockHash: '0x28f6d416c68dbbd698d1a0b0fdc4ce842694d82318a38ea6395413fd15397642', blockNumber: 12, address: '0xFB88dE099e13c3ED21F80a7a1E49f8CAEcF10df6', type: 'mined', id: 'log_e5cfee46', returnValues: [Result], event: 'Transfer', signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', raw: [Object] } } }
第二次运行会打印出账号2的余额
代码优化,由于开发阶段 abi 接口经常变化,从 solc 编译的abi 文件中直接读取最为方便。
const fs = require ('fs'); var Web3 = require("web3"); var web3 = new Web3("http://localhost:9545"); var abi = JSON.parse(fs.readFileSync('MetaCoin.abi')); var address = "0xfb88de099e13c3ed21f80a7a1e49f8caecf10df6"; var tokenContract = new web3.eth.Contract(abi, address); tokenContract.methods.getBalance("0x627306090abab3a6e1400e9345bc60c78a8bef57").call(null,function(error,result){ console.log("getBalance "+result); });
10.7.4. event
下面以ERC20代币为例演示事件如何工作
neo@MacBook-Pro ~/ethereum/web3 % cat event.js fs = require('fs'); var net = require('net'); var Web3 = require('web3'); var web3 = new Web3('/Users/neo/Library/Ethereum/geth.ipc', net); console.log(web3.version) const abi = fs.readFileSync('output/TokenERC20.abi', 'utf-8'); const contractAddress = "0x70682386d0dE84B1e549DC3c4305CCB2D261b2a8"; const coinbase = "0xB94054c174995AE2A9E7fcf6c7924635FBa8ECF7"; const toAddress = "0xf56b81a2bcb964D2806071e9Be4289A5559BB0fA"; balanceWei = web3.eth.getBalance(coinbase); console.log(balanceWei); const contract = new web3.eth.Contract(JSON.parse(abi), contractAddress, { from: coinbase , gas: 100000}); contract.events.Transfer({ fromBlock: 0, toBlock:'latest' }, function(error, event){ console.log(event); }) .on('data', function(event){ console.log(event); // same results as the optional callback above }) .on('changed', function(event){ // remove event from local database }) .on('error', console.error);
运行后程序不会退出,会源源不断的打印出每笔交易
neo@MacBook-Pro ~/ethereum/web3 % node event.js { address: '0x70682386d0dE84B1e549DC3c4305CCB2D261b2a8', blockNumber: 0, transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000', transactionIndex: 0, blockHash: '0x0000000000000000000000000000000000000000000000000000000000000000', logIndex: 0, removed: false, id: 'log_247b1779', returnValues: Result { '0': '0xB94054c174995AE2A9E7fcf6c7924635FBa8ECF7', '1': '0xf56b81a2bcb964D2806071e9Be4289A5559BB0fA', '2': '10000000', from: '0xB94054c174995AE2A9E7fcf6c7924635FBa8ECF7', to: '0xf56b81a2bcb964D2806071e9Be4289A5559BB0fA', value: '10000000' }, event: 'Transfer', signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', raw: { data: '0x0000000000000000000000000000000000000000000000000000000000989680', topics: [ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', '0x000000000000000000000000b94054c174995ae2a9e7fcf6c7924635fba8ecf7', '0x000000000000000000000000f56b81a2bcb964d2806071e9be4289a5559bb0fa' ] } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论