网站首页 返回列表 像“草根”一样,紧贴着地面,低调的存在,冬去春来,枯荣无恙。 Dapp合约开发指南 24-11-29 14:14:26 字节波 389 <strong>`原创`转载请注明:</strong> 来源:<a href="https://www.btewave.com/">字节波博客</a> 出处:https://www.btewave.com/article/19 转载:欢迎转载,但必须保留此段声明;必须在文章中给出原文连接; ### 一、矿工费用说明 1、对于以太坊:矿工费用由两个参数决定: 1)、该笔交易所需要的gas数量, 越复杂的逻辑,花费的gas数量越多。 2)、当前以太坊的gas价格price. 这个取决于当前以太坊网络的交易情况,波动较大,有10 ~ 500范围都有可能, 也就是同一笔交易,花费的矿工费用有可能波动50倍。 2、对于波场:矿工费用由两部分组成,带宽和能量, 对应于RAM和CPU。 1. 带宽:每24小时,波场都会给每个帐户5000点的带宽,普通转帐一次大约消耗200带宽,也就是一天大概只能进行25次的免费交易 2. 能量:能量代表运行智能合约的过程中,会消耗的处理器资源,每一个能量代表处理器在运作智能合约时经过的每一微秒。 注意:每天不会有免费的能量被分配到每个帐户,需要冻结波场币TRX获得。 3. 帐户上的带宽和能量都有消耗完的时候,消耗完时,有两种方案可以进行交易 一是冻结帐户内的波场币,来换取更多的带宽和能量, 二是实际支付额外的波场币做为手续费。如果选择不冻结波场币,直接付手续费的话,一次转帐大概会需要0.7TRX。 ### 二、 合约开发注意事项 1. 合约对外提供接口, 如果接口只是提供数据查询服务, 那么加上view 关键字修饰。这时从外部调用这个接口是不需要付矿工费用的。但是,如果这个加了view关键字修饰的接口,被合约内部的其他接口调用,而这个接口又没有被view 关键字修饰,还是要支付矿工费用 2. 合约不同于中心化程序,对于需要修改链上状态数据的接口,合约的执行是需要花费矿工费用的,所以实现合约接口时,要避免去实现复杂的业务逻辑。 3. 矿工费用是有上限的,太复杂的业务逻辑,可能由于矿工费用不足,永远都不能调用成功。 ### 三.合约技术要点 1. 函数和状态变量的可见性 public修饰的变量和函数,任何用户或者合约都能调用和访问。 private修饰的变量和函数,只能在其所在的合约中调用和访问,即使是其子合约也没有权限访问。 internal 和 private 类似,不过, 如果某个合约继承自其父合约,这个合约即可以访问父合约中定义的“内部”函数。 external 与public 类似,只不过这些函数只能在合约之外调用 - 它们不能被合约内的其他函数调用。 2. fallback函数说明 在合约调用没有匹配到函数名,或者调用没有带任何数据时被自动调用。 在 Solidity 0.6 之前,合约要接收eth(以太坊)或trx(波场),要有fallback函数,且要加上payable属性。 如: function() payable external { } //fallback function 在 Solidity 0.6.0 之后,使用了一个新的关键字 receive 来表示合约可以接受以太币(注:波场目前只支持到 Solidity 0.5.12) 如: receive() payable external {} 3. 常用的合约的调用方式 call: 最常用的调用方式,调用后内置变量 msg 的值会修改为调用者,执行环境为被调用者的运行环境(合约的 storage)。 delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。 callcode: 调用后内置变量 msg 的值会修改为调用者,但执行环境为调用者的运行环境。 4. 节省GAS写法 1. 避免重复写入,最好一次在最后尽可能多地写入到存储变量。 不好的代码样例: uint256 public count; for (uint256 i = 0; i < 10; ++i) { ... ++count; } 好的代码样例: for (uint256 i = 0; i < 10; ++i) { ... } count += 10; 2. 变量排序对GAS的影响,变量声明的顺序也会影响Gas的消耗 由于EVM操作都是以32字节为单位执行的,因此编译器将尝试将变量打包成32字节集进行访问,以减少访问时间 contract MyContract { uint64 public a; uint64 public b; uint64 public c; uint64 public d; function test() { a = 1; b = 2; c = 3; d = 4; } } 执行test()时,看起来已经存储了四个变量。由于这四个变量之和恰好是32个字节,因此实际执行了一个SSTORE。这只需要20,000 GAS。 再看下一个例子: contract MyContract { uint64 public a; uint64 public b; byte e; uint64 public c; uint64 public d; function test() { a = 1; b = 2; c = 3; d = 4; } } 中间插入了另一个变数,结果造成a,b,e和c会被分为一组,d独立为一组。同样的test()造成两次写入,消耗40000 Gas。 最后再看一个例子: contract MyContract { uint64 public a; uint64 public b; uint64 public c; uint64 public d; function test() { a = 1; b = 2; // ... do something c = 3; d = 4; } } 这与第一个例子的区别在于,在存储a和b之后,完成了其他事情,最后存储了c和d。结果这次将导致两次写入。因为当执行“执行某事”时,编译器确定打包操作已结束,然后发送写入。但是,由于第二次写入是同一组数据,因此认为它是被修改的。将消耗总共25,000个Gas。 建议: 根据上述原则,我们可以很容易地知道如何处理它。正确的排序和分组 将数据大小分组为32个字节,并将通常同时更新的变量放在一起。 不好的代码例子: contract MyContract { uint128 public hp; uint128 public maxHp; uint32 level; uint128 public mp; uint128 public maxMp; } 好的例子: contract MyContract { uint128 public hp; uint128 public mp; uint128 public maxHp; uint128 public maxMp; uint32 level; } 这里我们假设hp和mp更频繁地更新,并且maxHp和maxMp更频繁地一起更新。 尽量一次访问,不好的代码例子: function test() { hp = 1; // ... do something mp = 2; } 好的例子: function test() { // ... do something hp = 1; mp = 2; } 这个规则在struct上是一样的。 ### 四. 合约开发与部署 1. 以太坊合约开发环境:http://remix.ethereum.org/ 推荐使用sublime text开发,安装ethereum插件. 2. 编译与部署: 浏览器打开http://remix.ethereum.org/,如下图:  点击solidity,加载solidity合约文件,如下图  在左边栏点击红框图标,出现下图,里面有加载进来的合约文件  点击其中的合约文件,就可以进行solidity合约开发了。  3. 开发完成后,部署合约. 首先要安装浏览器钱包插件, 以太坊是MetaMask狐狸, 波场是TronLink。 安装好的MetaMask和TronLink,   以MetaMask为例,登录后界面说明:   合约编译:以太坊为例 如图,在编译面板,可以指定编译器版本,编译选项,获取到ABI接口说明文件,以及字节码文件。  合约部署发布: 需要说明下ENVIRONMENT这个选项。 1. JavaScript VM,表示把合约发布到本地,用于本地临时测试,一旦本页面重新加载,那么合约里的数据都会丢失。  2. Injected Web3这个选项是我们比较常用的。它指定把合约发布到网络上,具体是那条链,由前面所介绍的钱包插件当前连的网络决定。如钱包是连接到主网,那么就是把合约发布到主网上,这时花费的矿工费用就是真实的费用了。如钱包连接的是测试网或者私链网络, 那么就是把合约发布到测试网或者私链上, 如下图,就是把合约发布到私链Id为10088的网络上去。开发阶段,我们会经常把合约发布到私链上进行调试、测试。  Gas及ETh数额指定: 当合约方法需要接收ETH时,需要在VALUE框里指定转出的ETH数额。  合约发布:  钱包弹出用户授权界面:  对于已经部署的合约,我们也可以重新加载进来调试,调用。不需要重新再发布新的合约,需要注意合约地址和网络的一致性,不能把私链上的合约地址加载到主网上去。如图:  合约调用、调试:  波场合约部署,基本和以太坊差不多,目前波场支持的solidity版本是0.5.12 波场合约编译部署地址: http://www.tronide.io/ 1. 面板激活, 和以太坊Remix不同的是,首次使用tronide时,需要把相应的面板激活,要不在左边栏会找不到对应该的图标。  2. 合约开发面板,基本和以太坊差不多  3. 合约编译面板,基本和以太坊差不多  4. 合约发布面板: 这里多了Tokenid 和TokenValue,这个是指可以往合约发送trc10的代币,基于trc10的代币都有tokentid, tokenvalue是指代币的数额。  5. 工具面板,主要看Base58Check_HexString, 提供了Base58编码地址和十六进制地址转换工具。波场用户使用的地址一般都是经过Base58编码地址,但合约里面的地址变量只能接受十六进制地址,这个时候就需要使用Base58Check_HexString来转换。 Base58编码地址示例:TEeUCECr42Bvsx243a16kGErXd9mkr2iYk 对应的十六进制地址:0x334d686397970Ba2DC89E1B80bc422481DB8a83E  关键字词[Solidity, DAPP开发] 分享到: 上一篇:ansible学习记录-远程开启exe不能挂起UI界面 如需留言,请 登录,没有账号?请 注册 0 条评论 0 人参与 最新文章 Dapp合约开发指南 ansible学习记录-远程开启exe不能挂起UI界面 leetcode基础算法学习之maxArea leetcode基础算法学习之ReverseInt leetcode基础算法学习之LongestSubstr leetcode基础算法学习之addTwoNumbers leetcode基础算法学习之FindIndex CentOS7安装nginx服务 点击排行 优雅的语言开发优雅的站点 Beego框架第1节——环境与初始 Golang学习笔记之匿名函数与闭包 Golang学习笔记之interface Dapp合约开发指南 最新评论 字节波 官方 1年前 你好,可以,麻烦你的站点做好友链 字节波 官方 1年前 欢迎各界人士评论留言,注意要遵守法律法规,祝每一位... 友情链接 BYTE STUDIO 字节波 ByteWave 360导航 360安全浏览器
0 条评论 0 人参与