您的位置 首页 > 德语词汇

truffle是什么意思 以太坊开发框架Truffle从入门到实战

这篇文章给大家聊聊关于truffle是什么意思,以及以太坊开发框架Truffle从入门到实战对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

通过本文的学习和时间,你将熟悉以太坊开发框架Truffle的配置和运行,并借助Truffle完成一个智能合约的部署。

truffle是什么意思 以太坊开发框架Truffle从入门到实战

通过本文的学习,你将掌握以下内容:

2,了解TRUFFLE的安装,配置和启动

3,借助TRUFFLE完成METACOIN一个智能合约的运行

【实操课程列表】

第一课如何在WINDOWS环境下搭建以太坊开发环境

第二课如何实现以太坊最简智能合约“HelloWorld”的运行

第四课以太坊开发框架Truffle从入门到实战

第六课技术小白如何开发一个DAPP区块链应用(以宠物商店为例)

第七课技术小白如何在45分钟内发行通证(TOKEN)并上线交易

第八课如何调试以太坊官网的智能合约众筹案例

【说明】未列出的课程为知识普及的非实操类课程,所有区块链文章参考“区块链入口”专栏。

Truffle是一个世界级的开发环境,测试框架,以太坊的资源管理通道,致力于让以太坊上的开发变得简单,Truffle有以下:

1.1TRUFFLE的安装

在Ubuntu命令上窗口输入以下命令,完成安装:

如果安装成功,可输入truffleversion名称,正常情况下会有版本显示:

Windows,Linux(推荐Ubuntu),或MacOSX

Truffle客户端

有许多的以太坊客户端可以选择。我们推荐在开发和部署时使用不同客户端。

适用开发的客户端

当开发基于Truffle的应用时,我们推荐使用EthereumJSTestRPC。它是一个完整的在内存中的区块链仅仅存在于你开发的设备上。它在执行交易时是实时返回,而不等待默认的出块时间,这样你可以快速验证你新写的代码,当出现错误时,也能即时反馈给你。它同时还是一个支持自动化测试的功能强大的客户端。Truffle充分利用它的特性,能将测试运行时间提速近90%。

适用正式发布的客户端

对此有许多官方和非官方的以太坊客户端可供选择。最好使用TestRPC客户端充分测试后,再使用这些客户端。这些是完整的客户端实现,包括挖矿,网络,块及交易的处理,Truffle可以在不需要额外配置的情况下发布到这些客户端。

私人网络中使用了相同的技术,但却有不同的配置。所以你可以将上面提及的客户端来运行一个私有的网络,部署到这样的网络也是使用同样的方式。

【说明】作者使用TestRPC和Geth(go-ethereum)这2种客户端,他们的安装方式参考文章:https://www.jianshu.com/p/683ea7d62a39

2.1MetaCoin初始化

我们假设前面的安装和环境搭建已全部成功,此时应该可以直接使用命令truffle了,下面我们建立一个工作间truffle-workspace,然后在工作间执行:

mkdirMetaCoin\ncdMetaCoin\ntruffleunboxmetacoin\n

原来使用truffleinit,但现在它存在于unbox。

Truffle的盒子Boxs装有很多非常实用的项目样板,可以让你忽略一些环境配置问题,从而可以集中与开发你自己的DApp的业务唯一性。除此之外,TruffleBoxes能够容纳其他有用的组件、Solidity合约或者库,前后端视图等等。所有这些都是一个完整的实例Dapp程序。都可以下载下来逐一研究,寻找适合自己公司目前业务模型的组件。

可以看到,现在官方盒子还不多,总共7个,有三个是关于react的,两个是truffle自己的项目,可以下载体验,剩下两个是我们比较关心的,一个是metacoin,非常好的入门示例,另一个是webpack,顾名思义,它是一套比起metacoin更加完整的模板的存在。既然我们是初学,下面我们就从metacoin入手学习。

1)tutorialtoken

1]ThisboxhasallyouneedtogetstartedwithourOpenZeppelin(TutorialToken)tutorial.

2]https://truffleframework.com/boxes/tutorialtoken

1]ThisboxhasallyouneedtogetstartedwithourPetShoptutorial.

2]https://truffleframework.com/boxes/pet-shop

4)ENDLESS-NAMELESS-INC/CHESHIRE(加密猫)

1]AnEthereumtestnetrunningtheCryptoKittiessmartcontracts

AnHTTPserverrunningaminimalimplementationoftheCryptoKittieswebAPI:

AsimpleNode.jsframeworkforseedingthedevelopmentenvironmentwithrealisticdataandbootstrapingyourdApp.

2]https://truffleframework.com/boxes/cheshire

2.2目录结构及文件解读

进入metacoin目录,当前目录已经被初始化成一个新的空的以太坊工程,目录结构如下:

初始化文件解释1:Migrations.sol

pragmasolidity^0.4.2;\ncontractMigrations{\naddresspublicowner;\nuintpubliclast_completed_migration;\nmodifierrestricted(){\nif(msg.sender==owner)_;\n}\nfunctionMigrations()public{\nowner=msg.sender;\n}\nfunctionsetCompleted(uintcompleted)publicrestricted{\nlast_completed_migration=completed;\n}\nfunctionupgrade(addressnew_address)publicrestricted{\nMigrationsupgraded=Migrations(new_address);\nupgraded.setCompleted(last_completed_migration);\n}\n}\n

上面我们学习了Solidity具体的类型语法,我们来分析一下这个文件:

Solidity语法补充说明1:functionmodifier

modifier的使用方法,就看上面的Migrations合约的例子即可,它可以自动改变函数的行为,例如你可以给他预设一个条件,他会不断检查,一旦符合条件即可走预设分支。它可以影响当前合约以及派生合约。

pragmasolidity^0.4.11;\ncontractowned{\nfunctionowned()public{owner=msg.sender;}\naddressowner;\n//这里仅定义了一个modifier但是没有使用,它将被子类使用,方法体在这里“_;”,这意味着如果owner调用了这个函数,函数会被执行,其他人调用会抛出一个异常。\nmodifieronlyOwner{\nrequire(msg.sender==owner);\n_;\n}\n}\n//通过is关键字来继承一个合约类,mortal是owned的子类,也叫派生类。\ncontractmortalisowned{\n//当前合约派生了owned,此方法使用了父类的onlyOwner的modifier\n//publiconlyOwner,这种写法挺让人困惑,下面给出了我的思考,暂理解为派生类要使用基类的modifier。\nfunctionclose()publiconlyOwner{\nselfdestruct(owner);\n}\n}\ncontractpriced{\n//Modifiers可以接收参数\nmodifiercosts(uintprice){\n//这里modifier方法体是通过条件判断,是否满足,满足则执行“_;”分支。\nif(msg.value>=price){\n_;\n}\n}\n}\ncontractRegisterispriced,owned{\nmapping(address=>bool)registeredAddresses;\nuintprice;\n//构造函数给全局变量price赋值。\nfunctionRegister(uintinitialPrice)public{price=initialPrice;}\n//payable关键字重申,如果不声明的话,函数关于以太币交易的操作都会被拒回。\nfunctionregister()publicpayablecosts(price){\nregisteredAddresses[msg.sender]=true;\n}\n//此派生类也要使用基类的modifier。\nfunctionchangePrice(uint_price)publiconlyOwner{\nprice=_price;\n}\n}\ncontractMutex{\nboollocked;\nmodifiernoReentrancy(){\nrequire(!locked);\nlocked=true;\n_;\nlocked=false;\n}\nfunctionf()publicnoReentrancyreturns(uint){\nrequire(msg.sender.call());\nreturn7;\n}\n}\n

又延伸出来一个盲点:require关键字,它是错误判断,提到assert就懂了,官方文档的解释为:

require(boolcondition):\nthrowsiftheconditionisnotmet-tobeusedforerrorsininputsorexternalcomponents.\n

总结一下modifier:

Solidity语法补充说明2:RestrictingAccess

限制访问一种针对合约的常见模式。但其实你永远不可能限制得了任何人或电脑读取你的交易内容或者你的合同状态。你可以使用加密增大困难,但你的合约就是用来读取数据的,那么其他人也会看到。所以,其实上面的modifieronlyOwner是一个特别好的可读性极高的限制访问的手段。

那么restricted关键字如何使用呢?

好吧,我刚刚带着modifier的知识重新看了上面的Migrations合约的内容发现,restricted并不是关键字,而是modifier的方法名,在其下的想增加该modifier功能的函数中,都使用了publicrestricted的方式来声明。

说到这里,我又明白了为什么要使用publiconlyOwner这种写法,因为public是函数可见性修饰符,onlyOwner是自定义的限制访问的modifier方法,他们都是关于函数使用限制方面的,所以会写在一起,可以假想一个括号将它俩括起来,他们占一个位置,就是原来属于public|private|internal|external的那个位置。

Solidity语法补充说明3:SpecialVariablesandFunctions

这一点很重要了,我们研究一下Solidity自身携带的特殊变量以及函数:

msg有两个属性,一个是msg.sender,另一个是msg.value,这两个值可以被任何external函数调用,包含库里面的函数。

注意谨慎使用block.timestamp,nowandblock.blockhash,因为他们都是有可能被篡改的。

初始化文件解释2:MetaCoin.sol

pragmasolidity^0.4.18;\nimport"./ConvertLib.sol";\n//这是一个简单的仿币合约的例子。它并不是标准的可兼容其他币或token的合约,\n//如果你想创建一个标准兼容的token,请转到https://github.com/ConsenSys/Tokens(TODO:一会儿我们再过去转)\ncontractMetaCoin{\nmapping(address=>uint)balances;//定义了一个映射类型变量balances,key为address类型,值为无符整型,应该是用来存储每个账户的余额,可以存多个。\neventTransfer(addressindexed_from,addressindexed_to,uint256_value);//Solidity语法event,TODO:见下方详解。\nfunctionMetaCoin()public{//构造函数,tx.origin查查上面,找到它会返回交易发送方的地址,也就是说合约实例创建时会默认为当前交易发送方的余额塞10000,单位应该是你的仿币。\nbalances[tx.origin]=10000;\n}\nfunctionsendCoin(addressreceiver,uintamount)publicreturns(boolsufficient){//函数声明部分没有盲点,方法名,参数列表,函数可见性,返回值类型定义。\nif(balances[msg.sender]<amount)returnfalse;//如果余额不足,则返回发送币失败\nbalances[msg.sender]-=amount;//否则从发送方余额中减去发送值,注意Solidity也有“-=”,“+=”的运算符哦\nbalances[receiver]+=amount;//然后在接收方的余额中加入发送值数量。\nTransfer(msg.sender,receiver,amount);//使用以上event关键字声明的方法\nreturntrue;\n}\nfunctiongetBalanceInEth(addressaddr)publicviewreturns(uint){//获取以太币余额\nreturnConvertLib.convert(getBalance(addr),2);//调用了其他合约的方法,TODO:稍后介绍ConvertLib合约时说明。\n}\nfunctiongetBalance(addressaddr)publicviewreturns(uint){//获取当前账户的仿币余额\nreturnbalances[addr];\n}\n}\n

Solidity语法补充说明4:Events

EventsallowtheconvenientusageoftheEVMloggingfacilities,whichinturncanbeusedto“call”JavaScriptcallbacksintheuserinterfaceofadapp,whichlistenfortheseevents.

Events提供了日志支持,进而可用于在用户界面上“调用”dappJavaScript回调,监听了这些事件。简单来说,我们的DApp是基于web服务器上的web3.js与EVM以太坊结点进行交互的,而智能合约是部署在EVM以太坊结点上的。举一个例子:

contractExampleContract{\n//somestatevariables...\nfunctionfoo(int256_value)returns(int256){\n//manipulatestate...\nreturn_value;\n}\n}\n

合约ExampleContract有个方法foo被部署在EVM的一个结点上运行了,此时用户如果想在DApp上调用合约内部的这个foo方法,如何操作呢,有两种办法:

第一种办法在方法本身比较耗时的情况下会阻塞,或者不会获取到准确的返回值。所以采用第二种办法:就是通过Solidity的关键字event。event在这里就是一个回调函数的概念,当函数运行结束以后(交易进块),会通过event返回给web3,也就是DApp用户界面相应的结果。这是以太坊一种客户端异步调用方法。关于这个回调,要在DApp使用web3时显示编写:

exampleEvent.watch(function(err,result){\nif(err){\nconsole.log(err)\nreturn;\n}\nconsole.log(result.args._value)\n//检查合约方法是否反返回结果,若有则将结果显示在用户界面并且调用exampleEvent.stopWatching()方法停止异步回调监听。\n})\n

写Solidity最大的不同在于,我们要随时计算好我们的gas消耗,方法的复杂度,变量类型的存储位置(memory,storage等等)都会决定gas的消耗量。

使用event可以获得比storage更便宜的gas消耗。

总结一下event,就是如果你的Dapp客户端web3.js想调用智能合约内部的函数,则使用event作为桥梁,它能方便执行异步调用同时又节约gas消耗。

初始化文件解释3:ConvertLib.sol

pragmasolidity^0.4.4;\nlibraryConvertLib{\nfunctionconvert(uintamount,uintconversionRate)publicpurereturns(uintconvertedAmount)\n{\nreturnamount*conversionRate;\n}\n}\n

与MetaCoin智能合约不同的是,ConvertLib是由library声明的一个库,它只有一个方法,就是返回给定的两个无符整数值相乘的结果。返回到上面的MetaCoin中该库的使用位置去分析,即可知道,MetaCoin的仿币的价格是以太币的一倍,所以MetaCoin是以以太币为标杆,通过智能合约发布的一个token,仿币。

这似乎就可以很好地解决我在《以太坊RPC机制与API实例》文章中需要发布三倍以太币的token的需求了,而我们完全不必更改以太坊源码,但那篇文章通过这个需求的路线研究了以太坊的Go源码也算功不可没。

初始化文件解释4:1_initial_migration.js

varMigrations=artifacts.require("./Migrations.sol");\nmodule.exports=function(deployer){\ndeployer.deploy(Migrations);\n};\n

这个js文件是nodejs的写法,看上去它的作用就是部署了上面的Migrations智能合约文件。

初始化文件解释5:2_deploy_contracts.js

varConvertLib=artifacts.require("./ConvertLib.sol");\nvarMetaCoin=artifacts.require("./MetaCoin.sol");\nmodule.exports=function(deployer){\ndeployer.deploy(ConvertLib);\ndeployer.link(ConvertLib,MetaCoin);\ndeployer.deploy(MetaCoin);\n};\n

这个文件是meatcoin智能合约的部署文件,里面约定了部署顺序,依赖关系。这里我们看到了MetaCoin智能合约是要依赖于库ConvertLib的,所以要先部署ConvertLib,然后link他们,再部署MetaCoin,这部分js的写法可以参照官方文档DEPLOYERAPI,主要就是介绍了一下deploy、link以及then三个方法的详细用法,不难这里不再赘述。

初始化文件解释6:truffle-config.js,truffle.js

//See<http://truffleframework.com/docs/advanced/configuration>

//tocustomizeyourTruffleconfiguration!

//See<http://truffleframework.com/docs/advanced/configuration>

//tocustomizeyourTruffleconfiguration!

这两个文件也都是nodejs,他们都是配置文件,可能作用域不同,目前它俩是完全相同的(因为啥也没有)。我们去它推荐的网站看一看。给出了一个例子:

module.exports={\nnetworks:{\ndevelopment:{\nhost:"127.0.0.1",\nport:8545,\nnetwork_id:"*"//Matchanynetworkid\n}\n}\n};\n

这个例子展示了该配置文件可以配置网络环境,暂先到这,以后遇上了针对该配置文件进行研究。

初始化文件解释7:.placeholder

Thisisaplaceholderfiletoensuretheparentdirectoryinthegitrepository.Feelfreetoremove.

翻译过来就是:placeholder文件是用来保证在git库中父级目录的,可以删除。

初始化文件解释8:metacoin.js

和下面的文件一样,他们的功能都是用来做单元测试的,truffle在编译期间会自动执行这些测试脚本。当前文件为js版本,模拟用户在DApp客户端用户界面操作的情形。

varMetaCoin=artifacts.require("./MetaCoin.sol");//这与1_initial_migration.js文件的头是一样的,引入了一个智能合约文件。\ncontract('MetaCoin',function(accounts){\nit("shouldput10000MetaCoininthefirstaccount",function(){\nreturnMetaCoin.deployed().then(function(instance){\nreturninstance.getBalance.call(accounts[0]);\n}).then(function(balance){\nassert.equal(balance.valueOf(),10000,"10000wasn'tinthefirstaccount");\n});\n});\nit("shouldcallafunctionthatdependsonalinkedlibrary",function(){\nvarmeta;\nvarmetaCoinBalance;\nvarmetaCoinEthBalance;\nreturnMetaCoin.deployed().then(function(instance){\nmeta=instance;\nreturnmeta.getBalance.call(accounts[0]);\n}).then(function(outCoinBalance){\nmetaCoinBalance=outCoinBalance.toNumber();\nreturnmeta.getBalanceInEth.call(accounts[0]);\n}).then(function(outCoinBalanceEth){\nmetaCoinEthBalance=outCoinBalanceEth.toNumber();\n}).then(function(){\nassert.equal(metaCoinEthBalance,2*metaCoinBalance,"Libraryfunctionreturnedunexpectedfunction,linkagemaybebroken");\n});\n});\nit("shouldsendcoincorrectly",function(){\nvarmeta;\n//Getinitialbalancesoffirstandsecondaccount.\nvaraccount_one=accounts[0];\nvaraccount_two=accounts[1];\nvaraccount_one_starting_balance;\nvaraccount_two_starting_balance;\nvaraccount_one_ending_balance;\nvaraccount_two_ending_balance;\nvaramount=10;\nreturnMetaCoin.deployed().then(function(instance){\nmeta=instance;\nreturnmeta.getBalance.call(account_one);\n}).then(function(balance){\naccount_one_starting_balance=balance.toNumber();\nreturnmeta.getBalance.call(account_two);\n}).then(function(balance){\naccount_two_starting_balance=balance.toNumber();\nreturnmeta.sendCoin(account_two,amount,{from:account_one});\n}).then(function(){\nreturnmeta.getBalance.call(account_one);\n}).then(function(balance){\naccount_one_ending_balance=balance.toNumber();\nreturnmeta.getBalance.call(account_two);\n}).then(function(balance){\naccount_two_ending_balance=balance.toNumber();\nassert.equal(account_one_ending_balance,account_one_starting_balance-amount,"Amountwasn'tcorrectlytakenfromthesender");\nassert.equal(account_two_ending_balance,account_two_starting_balance+amount,"Amountwasn'tcorrectlysenttothereceiver");\n});\n});\n});\n

我们来分析一波这个trufflemetacoinjs版本的单元测试:

这是官方文档,详细说明如何使用JS来编写智能合约的单元测试。

初始化文件解释9:TestMetacoin.sol

好下面来看看Solidity智能合约版本的单元测试。一般来讲,这种文件的命名规则是Test加待测智能合约的名字拼串组成。

pragmasolidity^0.4.2;\nimport"truffle/Assert.sol";\nimport"truffle/DeployedAddresses.sol";\nimport"../contracts/MetaCoin.sol";\ncontractTestMetacoin{\nfunctiontestInitialBalanceUsingDeployedContract()public{\nMetaCoinmeta=MetaCoin(DeployedAddresses.MetaCoin());\nuintexpected=10000;\nAssert.equal(meta.getBalance(tx.origin),expected,"Ownershouldhave10000MetaCoininitially");\n}\nfunctiontestInitialBalanceWithNewMetaCoin()public{\nMetaCoinmeta=newMetaCoin();\nuintexpected=10000;\nAssert.equal(meta.getBalance(tx.origin),expected,"Ownershouldhave10000MetaCoininitially");\n}\n}\n

继续分析:

这是官方文档,详细说明如何使用Solidity来编写智能合约的单元测试。

根据编译输出的路径地址./build/contracts,我们去查看一下

可以看到原来所在在contracts目录下的智能合约文件(有合约contract,有库library)均被编译成了json文件。

这些json文件就是truffle用来部署合约的编译文件。

2.4配置以太坊本地环境

truffle.js是truffle的配置文件,启动好以太坊本地结点以后,我们需要让truffle去识别它并使用它,这就需要在truffle.js中配置相关属性:

module.exports={\nnetworks:{\ndevelopment:{\nhost:"127.0.0.1",\nport:8545,\nnetwork_id:"*"//Matchanynetworkid\n}\n}\n};\n

【说明】如果不启动TestRPC,直接执行部署合约的话,会有以下错误提示:

2.5启动本地以太坊客户端结点

启动适合开发的RPC客户端

启动之前安装好的EthereumJSRPC客户端。

【说明】一定要启动一个新的客户端执行testrpc命令,可以观察到默认账户和私钥信息。

移植(migrate),对这里叫移植,但下面我们仍使用“部署”这个词,truffle中部署的命令为:

查看testrpc的输出窗口,可以看到这笔交易和花费的区块:

我们知道在执行编译时会自动执行这些单元测试,如果有一个测试未通过则会中断编译过程。而在开发阶段,我们也可以自己使用命令来测试。

没有报错就说明通过了,绿条“5passing(2s)”,有报错就会打印在下方。

3.1创建工程目录

返回父级目录,创建一个文件夹HelloWorld,来做为你的工程根目录。

3.2初始化框架

在工作目录HelloWorld目录下,执行truffle初始化动作:

采用SFTP下载文件到本地,可查看目录结构:

│truffle-config.js\n│truffle.js\n│\n├─contracts\n│Migrations.sol\n│\n├─migrations\n│1_initial_migration.js\n│\n└─test\n

目录结构简单说明如下:

contract/-Truffle默认的合约文件存放地址。

test/-用来测试应用和合约的测试文件

3.3新建新合约

在./contract目录下创建一个自己的合约文件Greeter.sol。

pragmasolidity^0.4.17;\ncontractGreeter\n{\naddresscreator;\nstringgreeting;\nfunctionGreeter(string_greeting)public\n{\ncreator=msg.sender;\ngreeting=_greeting;\n}\n\nfunctiongreet()publicconstantreturns(string)\n{\nreturngreeting;\n}\n\nfunctionsetGreeting(string_newgreeting)public\n{\ngreeting=_newgreeting;\n}\n\n/**********\nStandardkill()functiontorecoverfunds\n**********/\n\nfunctionkill()public\n{\nif(msg.sender==creator)\nsuicide(creator);//killsthiscontractandsendsremainingfundsbacktocreator\n}\n}\n

3.4新建发布脚本

在./migrations/目录下新建一个文件:2_deploy_contracts.js,增加发布代码。

varGreeter=artifacts.require("./Greeter.sol");\nmodule.exports=function(deployer){\ndeployer.deploy(Greeter,"Hello,World!");//"参数在第二个变量携带"\n};\n

3.5编译

进入到工程根目录./HelloWorld目录下,进行编译:

3.6启动你的客户端

如果之前没有启动RPC客户端的话,则需要启动之前安装好的EthereumJSRPC客户端。如果已启动的则忽略此步。

3.7部署合约(migrate)

执行部署命令(trufflemigrate)提示出错。

修改文件./HelloWorld/truffle.js文件,增加网络配置:

module.exports={\n//See<http://truffleframework.com/docs/advanced/configuration>\n//tocustomizeyourTruffleconfiguration!\nnetworks:{\ndevelopment:{\nhost:"localhost",\nport:8545,\nnetwork_id:"*"//匹配任何networkid\n}\n}\n};\n

重新执行编译命令,重新执行部署命令(trufflemigrate),则运行正确。对应Greeter的智能合约地址为“0x7d62724f397a99613b84923a1166d683de2db680”

3.8TRUFFLE测试环境运行合约

Truffle提供了一种更加简单的方式,通过交互式控制台来与你的那些准备好的合约进行交互。

truffleconsole

一个基本的交互控制台,可以连接任何EVM客户端。如果你已经有了自己的ganache或者geth等EVM的本地环境,那么就可以使用truffleconsole来交互,所以如果你已经有一个现成的小组共享的开发用EVM,那么使用这个没错。

truffledevelop

一个交互控制台,启动时会自动生成一个开发用区块链环境(其实我认为它与ganache就是一个底层实现机制,都是默认生成10个账户)。如果你没有自己的EVM环境的话,直接使用truffledevelop非常方便。

输入Greeter智能合约命令,显示打印出一个json结构,展示了它的各种属性内容。

根据你的Greeter智能合约地址,运行Greeter智能合约命令:

3.8GETH正式环境运行合约

本节假设GETH环境已安装好了。如果还没有安装的同学,可参考文章《第一课如何在WINDOWS环境下搭建以太坊开发环境》(https://www.jianshu.com/p/683ea7d62a39)的描述步骤。

然后在IDE内部打开一个terminal,启动GETH的EVM环境。

geth--datadirtestNet3--dev--rpcconsole

GETH中是通过abi来注册合约对象的。

首先我们找到./build/contracts/Greeter.json中的abi的value:

"abi":[\n{\n"inputs":[\n{\n"name":"_greeting",\n"type":"string"\n}\n],\n"payable":false,\n"stateMutability":"nonpayable",\n"type":"constructor"\n},\n{\n"constant":true,\n"inputs":[],\n"name":"greet",\n"outputs":[\n{\n"name":"",\n"type":"string"\n}\n],\n"payable":false,\n"stateMutability":"view",\n"type":"function"\n},\n{\n"constant":false,\n"inputs":[\n{\n"name":"_newgreeting",\n"type":"string"\n}\n],\n"name":"setGreeting",\n"outputs":[],\n"payable":false,\n"stateMutability":"nonpayable",\n"type":"function"\n},\n{\n"constant":false,\n"inputs":[],\n"name":"kill",\n"outputs":[],\n"payable":false,\n"stateMutability":"nonpayable",\n"type":"function"\n}\n],\n

通过json压缩成一行得到

varabi=[{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newgreeting","type":"string"}],"name":"setGreeting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];

重新部署智能合约到Geth环境

获得Greeter的地址为0xb52bb3ce336f71a14345c78e5b2f8e63685e3f92

切换到GETH环境下,利用api和智能合约地址(你自己Greeter智能合约的地址哦)注册合约对象。

varabi=[{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newgreeting","type":"string"}],"name":"setGreeting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];\nvarHelloWorld=eth.contract(abi).at('0xb52bb3ce336f71a14345c78e5b2f8e63685e3f92')\nHelloWorld.greet()\n

输出截图显示成功:

本文站在巨人的肩膀上,完成了以太坊开发框架Truffle从入门到实战的演示。对巨人的文章表示感谢:

1,Solidity的Truffle框架实战(手把手)

http://truffleframework.com/docs/

4,官网GITHUB的代码:https://github.com/trufflesuite

知识对接服务:

辉哥和欧阳哥哥在知识星球开通了区块链入门专栏,用于存放简书区块链入门专栏文章的工程源码等内容,并建立专项微信群用于技术交流,欢迎加入。

END,本文到此结束,如果可以帮助到大家,还望关注本站哦!

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023