




已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一 智能合约开发语言:solidityIDE:mix-ide or whatever实例编写,Conference.sol:contract Conference address public organizer; mapping (address = uint) public registrantsPaid; uint public numRegistrants; uint public quota; event Deposit(address _from, uint _amount); / so you can log these events event Refund(address _to, uint _amount); function Conference() / Constructor organizer = msg.sender; quota = 500; numRegistrants = 0; function buyTicket() public returns (bool success) if (numRegistrants = quota) return false; registrantsPaidmsg.sender = msg.value; numRegistrants+; Deposit(msg.sender, msg.value); return true; function changeQuota(uint newquota) public if (msg.sender != organizer) return; quota = newquota; function refundTicket(address recipient, uint amount) public if (msg.sender != organizer) return; if (registrantsPaidrecipient = amount) address myAddress = this; if (myAddress.balance = amount) recipient.send(amount); registrantsPaidrecipient = 0; numRegistrants-; Refund(recipient, amount); function destroy() / so funds not locked in contract forever if (msg.sender = organizer) suicide(organizer); / send funds to organizer 二 智能合约部署使用truffle部署智能合约的步骤:1.truffle init(在新目录中) = 创建truffle项目目录结构2. 编写合约代码,保存到contracts/YourContractName.sol文件。3. 把合约名字加到config/app.json的contracts部分。4. 启动以太坊节点(例如在另一个终端里面运行testrpc)。5.truffle deploy(在truffle项目目录中)添加一个智能合约。在truffle init执行后或是一个现有的项目目录中,复制粘帖上面的会议合约到contracts/Conference.sol文件中。然后打开truffle.js文件,把Conference加入deploy数组中。启动testrpc。在另一个终端中启动testrpc。编译或部署。执行truffle compile看一下合约是否能成功编译,或者直接truffle deploy一步完成编译和部署。这条命令会把部署好的合约的地址和ABI(应用接口)加入到配置文件中,这样之后的truffle test和truffle build步骤可以使用这些信息。出错了?编译是否成功了?记住,错误信息即可能出现在testrpc终端也可能出现在truffle终端。重启节点后记得重新部署!如果你停止了testrpc节点,下一次使用任何合约之前切记使用truffle deploy重新部署。testrpc在每一次重启之后都会回到完全空白的状态。部署truffle deploy启动服务truffle serve启动服务后,可以在浏览器访问项目:http:/localhost:8080/三 智能合约测试用例编写/ 测试用例编写/ 把项目目录test/中的example.js文件重命名为conference.js,内容修改为如下,然后启动testrpc后,运行/ Truffle testcontract(Conference, function(accounts) / 1. 初始化一个新的Conference,然后检查变量是否都正确赋值 it(Initial conference settings should match, function(done) var conference = Conference.at(Conference.deployed_address); / same as previous example up to here Conference.new( from: accounts0 ) .then(function(conference) conference.quota.call().then( function(quota) assert.equal(quota, 500, Quota doesnt match!); ).then( function() return conference.numRegistrants.call(); ).then( function(num) assert.equal(num, 0, Registrants should be zero!); return anizer.call(); ).then( function(organizer) assert.equal(organizer, accounts0, Owner doesnt match!); done(); / to stop these tests earlier, move this up).catch(done); ).catch(done); );/ 2. 测试合约函数调用 测试改变Quote变量的函数能否工作it(Should update quota, function(done) var c = Conference.at(Conference.deployed_address); Conference.new(from: accounts0 ).then( function(conference) conference.quota.call().then( function(quota) assert.equal(quota, 500, Quota doesnt match!); ).then( function() return conference.changeQuota(300);).then( function(result) / result here is a transaction hash console.log(result); / if you were to print this out itd be long hex - the transaction hash return conference.quota.call().then( function(quota) assert.equal(quota, 300, New quota is not correct!); done();).catch(done); ).catch(done););/ 3. 测试交易 调用一个需要发起人发送资金的函数。it(Should let you buy a ticket, function(done) var c = Conference.at(Conference.deployed_address); Conference.new( from: accounts0 ).then( function(conference) var ticketPrice = web3.toWei(.05, ether); var initialBalance = web3.eth.getBalance(conference.address).toNumber(); conference.buyTicket( from: accounts1, value: ticketPrice ).then(function() var newBalance = web3.eth.getBalance(conference.address).toNumber(); var difference = newBalance - initialBalance; assert.equal(difference, ticketPrice, Difference should be what was sent); return conference.numRegistrants.call(); ).then(function(num) assert.equal(num, 1, there should be 1 registrant); return conference.registrantsPaid.call(accounts1); ).then(function(amount) assert.equal(amount.toNumber(), ticketPrice, Senders paid but is not listed); done(); ).catch(done); ).catch(done););/ 4. 测试包含转账的合约 最后,为了完整性,确认一下refundTicket方法能正常工作,而且只有会议组织者能调用it(Should issue a refund by owner only, function(done) var c = Conference.at(Conference.deployed_address); Conference.new( from: accounts0 ).then( function(conference) var ticketPrice = web3.toWei(.05, ether); var initialBalance = web3.eth.getBalance(conference.address).toNumber(); conference.buyTicket( from: accounts1, value: ticketPrice ).then(function() var newBalance = web3.eth.getBalance(conference.address).toNumber(); var difference = newBalance - initialBalance; assert.equal(difference, ticketPrice, Difference should be what was sent); / same as before up to here / Now try to issue refund as second user - should fail return conference.refundTicket(accounts1, ticketPrice, from: accounts1); ).then( function() var balance = web3.eth.getBalance(conference.address).toNumber(); assert.equal(web3.toBigNumber(balance), ticketPrice, Balance should be unchanged); / Now try to issue refund as organizer/owner - should work return conference.refundTicket(accounts1, ticketPrice, from: accounts0); ).then( function() var postRefundBalance = web3.eth.getBalance(conference.address).toNumber(); assert.equal(postRefundBalance, initialBalance, Balance should be initial balance); done();).catch(done); ).catch(done); ); );/ Solidity编译器提供了一个参数让你可以从命令行获取合约的Gas开销概要/ solc -gas Conference.sol/ 输出:= Conference =Gas estimation:construction: 45438 + 271200 = 316638external: registrantsPaid(address):323 organizer():282 refundTicket(address,uint256):? destroy():384 changeQuota(uint256):20370 quota():333 numRegistrants():355 buyTicket():42023internal:四 为合约创建DApp界面 1. 修改app/javascripts/app.jswindow.onload = function() var accounts = web3.eth.accounts;var conference = Conference.at(Conference.deployed_address);$(#confAddress).html(Conference.deployed_address);var myConferenceInstance;Conference.new(from: accounts0, gas: 3141592).then(function(conf) myConferenceInstance = conf;checkValues(); );/ Check Valuesfunction checkValues() myConferenceInstance.quota.call().then(function(quota) $(input#confQuota).val(quota);return myConferenceIanizer.call();).then(function(organizer) $(input#confOrganizer).val(organizer);return myConferenceInstance.numRegistrants.call(); ).then(function(num) $(#numRegistrants).html(num.toNumber();return myConferenceIanizer.call(););/ Change Quotafunction changeQuota(val) myConferenceInstance.changeQuota(val, from: accounts0).then(function() return myConferenceInstance.quota.call();).then(function(quota) if (quota = val) var msgResult;msgResult = Change successful; else msgResult = Change failed;$(#changeQuotaResult).html(msgResult););/ buyTicketfunction buyTicket(buyerAddress, ticketPrice) myConferenceInstance.buyTicket( from: buyerAddress, value: ticketPrice ).then(function() return myConferenceInstance.numRegistrants.call();).then(function(num) $(#numRegistrants).html(num.toNumber();return myConferenceInstance.registrantsPaid.call(buyerAddress);).then(function(valuePaid) var msgResult;if (valuePaid.toNumber() = ticketPrice) msgResult = Purchase successful; else msgResult = Purchase failed;$(#buyTicketResult).html(msgResult););/ refundTicketfunction refundTicket(buyerAddress, ticketPrice) var msgResult;myConferenceInstance.registrantsPaid.call(buyerAddress).then(function(result) if (result.toNumber() = 0) $(#refundTicketResult).html(Buyer is not registered - no refund!); else myConferenceInstance.refundTicket(buyerAddress, ticketPrice, from: accounts0).then(function() return myConferenceInstance.numRegistrants.call();).then(function(num) $(#numRegistrants).html(num.toNumber();return myConferenceInstance.registrantsPaid.call(buyerAddress);).then(function(valuePaid) if (valuePaid.toNumber() = 0) msgResult = Refund successful; else msgResult = Refund failed;$(#refundTicketResult).html(msgResult);););/ createWalletfunction createWallet(password) var msgResult;var secretSeed = lightwallet.keystore.generateRandomSeed();$(#seed).html(secretSeed);lightwallet.keystore.deriveKeyFromPassword(password, function (err, pwDerivedKey) console.log(createWallet);var keystore = new lightwallet.keystore(secretSeed, pwDerivedKey);/ generate one new address/private key pairs/ the corresponding private keys are also encryptedkeystore.generateNewAddress(pwDerivedKey);var address = keystore.getAddresses()0;var privateKey = keystore.exportPrivateKey(address, pwDerivedKey);console.log(address);$(#wallet).html(0x+address);$(#privateKey).html(privateKey);$(#balance).html(getBalance(address);/ Now set ks as transaction_signer in the hooked web3 provider/ and you can start using web3 using the keys/addresses in ks!switchToHooked3(keystore););function getBalance(address) return web3.fromWei(web3.eth.getBalance(address).toNumber(), ether);/ switch to hooked3webprovider which allows for external Tx signing/ (rather than signing from a wallet in the Ethereum client)function switchToHooked3(_keystore) console.log(switchToHooked3);var web3Provider = new HookedWeb3Provider( host: http:/localhost:8545, / check what using in truffle.js transaction_signer: _keystore);web3.setProvider(web3Provider);function fundEth(newAddress, amt) console.log(fundEth);var fromAddr = accounts0; / default owner address of clientvar toAddr = newAddress;var valueEth = amt;var value = parseFloat(valueEth)*1.0e18;var gasPrice = 1000000000000;var gas = 50000;web3.eth.sendTransaction(from: fromAddr, to: toAddr, value: value, function (err, txhash) if (err) console.log(ERROR: + err) console.log(txhash: + txhash + ( + amt + in ETH sent);$(#balance).html(getBalance(toAddr););/ Wire up the UI elements$(#changeQuota).click(function() var val = $(#confQuota).val();changeQuota(val););$(#buyTicket).click(function() var val = $(#ticketPrice).val();var buyerAddress = $(#buyerAddress).val();buyTicket(buyerAddress, web3.toWei(val););$(#refundTicket).click(function() var val = $(#ticketPrice).val();var buyerAddress = $(#refBuyerAddress).val();refundTicket(buyerAddress, web3.toWei(val););$(#createWallet).click(function() var val = $(#password).val();if (!val) $(#pass
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 菌群移植生物标志物-第1篇-洞察及研究
- 油墨厂搅拌桨磨损细则
- 江苏省苏州市昆山市秀峰中学2025-2026学年上学期七年级9月月考数学卷(含答案)
- 2024-2025学年湖南省张家界市高二(下)期末物理试卷(含答案)
- 印刷厂油墨存储管理规定
- 手受伤后安全培训课件
- 社区结构预测-洞察及研究
- 手势小星星课件
- 中国银行新员工思想汇报模板图文
- 咨询工程师《项目决策分析与评价》考试题(附答案)
- ISO 22000-2018食品质量管理体系-食品链中各类组织的要求(2023-雷泽佳译)
- 卡巴斯基应急响应指南
- 理财规划大赛优秀作品范例(一)
- 2023年四川能投筠连电力招聘笔试参考题库附带答案详解
- 护理管理组织结构与设计
- 静配中心清洁消毒考核试题
- 一级烟草专卖管理师理论考试题库(含答案)
- 小学数学《分数除法》50道应用题包含答案
- 碳捕集、利用与封存技术课件
- 化工试生产总结报告
- 复句与单句的辨析课件
评论
0/150
提交评论