首页 » Web前端 » php挪用合约技巧_BSN智能合约开拓培训CITA三

php挪用合约技巧_BSN智能合约开拓培训CITA三

duote123 2024-12-11 0

扫一扫用手机浏览

文章目录 [+]

  1

  智能合约的定义

php挪用合约技巧_BSN智能合约开拓培训CITA三

  1994年,打算机科学家和密码学家 Nick Szabo 首次提出“智能合约”观点。
它早于区块链观点的出身。
Szabo 描述了什么是“以数字形式指定的一系列承诺,包括各方履行这些承诺的协议”。
虽然有它的好处,但智能合约的想法一贯未取得进展——紧张是缺少可以让它发挥出浸染的区块链。

php挪用合约技巧_BSN智能合约开拓培训CITA三
(图片来自网络侵删)

  直到 2008 年,第一个加密货币比特币才涌现,同时引入了当代区块链技能。
区块链最初因此比特币的底层技能涌现的,各种区块链分叉导致发生很大的变革。
智能合约在 2008 年依然无法融入比特币区块链网络,但在五年后,以太坊让它浮出水面。
从此,呈现出了各种不同形式的智能合约,个中以太坊智能合约利用最广。

  自以太坊开始,区块链是一个运行着智能合约的分布式平台:运用程序可以按照程序运行,不存在故障、审查、敲诈或第三方干预的可能性。
智能合约给予了我们利用区块链技能来验证我们运行的代码的实行情形的能力。

  智能合约定义

  智能合约(英语:Smart contract )是一种旨在以信息化办法传播、验证或实行的打算机协议。
智能合约许可在没有第三方的情形下进行可信交易,这些交易可追踪且不可逆转。

  智能合约大略定义便是智能合约是可以处理 token 的脚本,环绕它可以发行,转移和销毁资产。
这里说的资产是一个泛化的定义,不一定是币,可以是任何一种虚拟物品(比如应收,支付信息乃至加密猫)和现实天下的物品在区块链上的映射(比如舱单,抵押)。

  CITA 智能合约

  CITA 区块链框架利用的虚拟机 CITA-VM 和 EVM 采纳同样的指令集,以是合约所利用的措辞也是 solidity。
由于 Ethereum 是目前环球最广泛的区块链网络,以是 solidity 也是利用最广泛的智能合约措辞,环绕它的生态是非常丰富的,包括了合约调试,支配工具和保护合约安全的一些库。

  这里再谈一下合约是由谁来实行的问题,在公链上,比如比特币或者以太坊,这些合约由我们称为“矿工”的参与方逼迫实行和证明。
矿工实在是多台电脑(也可以称为矿机),它们把一项交易(实行智能合约,代币转账等) 以区块的形式添加到一个公开分账本上。
利用者给这些矿工支付 “Gas”也便是手续费,它是运行一份合约的本钱。

  由于 CITA 是针对付企业的开放容许链框架,在 CITA 中矿工是出块节点,利用智能合约所须要的手续费是支付给出块节点的, gas 在这里叫做 quota。
当然这里支付比例是可以自定义调度的,详细可以见文档。
同时 CITA 可以调节为无币模式,在无币模式下,不存在手续费。

  2

  智能合约开拓

  现在,我们开始智能合约的开拓部分,Solidity 与 Javascript 很靠近,但它们并不相同。
而且不能在一段代码上强加 JQuery,智能合约是无法调用区块链体系之外的代码的。
同时还有一个特点是,你在开拓的时候须要特殊把稳安全性,由于在区块链上的交易是不可逆的。

  智能合约定义

  通过一个例子解释基本语法,这里参考了 ethfans 上的一个例子,如果难以理解的话可以换一个,利用当时 PeckShield 讲的一个分饼干的例子。

  现在,关于我们的第一个例子,我正在考虑一个由电影《韶光方案局》启示的脚本。
电影中,人们生活在一个反乌托邦式的未来,改用韶光作为货币流利。
他们可以通过掰手腕的办法赢取对手的韶光(他们的“手臂”上存储着韶光,输方的韶光将会传送给赢家),我们也可以这么做!
用智能合约以角力( Wrestling )的办法赢利。

  首先,solidity 脚本的根本是下面这段代码,pragma 指明正在利用的 Solidity 版本。
Wrestling 是合约的名称,是一种与 Javascrip 上的类(class)相似的构造。

  

  我们须要两个参与者,以是我们要添加两个保存他们账户地址的变量(他们的公钥),分别是 wrestler1 和 wrestler2 ,变量声明办法如下。

  

  在我们的小游戏中,每一轮的比赛,参与者都可以投入一笔钱,如果一个人投入的钱是另一个人的两倍(总计),那他就赢了。
定义两个玩家是否已经投入的flagwrestler1Played和wrestler2Played以及两位玩家投入的金额wrestler1Deposit和wrestler1Deposit。

 

  还有判断游戏结束与否,赢家和收益的变量。

  

  下面先容一些关于公钥/私钥的规则,在区块链上每一个账户都是一对公私钥,私钥可以对一个信息进行署名,从而使这条信息可以被他人验证,被验证的时候它的公钥须要被利用到。
在全体署名和验证的过程中,没有信息是加密的,实际上任何信息都是公开课查验的。

  对付合约里面的变量,实质上来讲,也是可以被公开访问的。
在这里要把稳是的,纵然一个变量是私有的,并不是说其他人不能读取它的内容,而是意味着它只能在合约中被访问。
但实际上,由于全体区块链存储在许多打算机上,以是存储在变量中的信息总是可以被其他人看到,这是在区块链中一个很主要额原则。

  另一方面,和很多编程措辞很像,编译器会自动为公共变量创建 getter 函数。
为了使其他的合约和用户能够变动公共变量的值,关照也须要针对不同的变量创建一个 setter 函数。

  现在我们将为游戏的每一步添加三个事宜。

  开始,参与者注册;

  游戏期间,登记每一轮赛果;

  末了,个中一位参与者得胜。

  事宜是大略的日志,可以在分布式运用程序(也称为 dapps)的用户界面中调用 JavaScript 回调函数。
在开拓过程中,事宜乃至可以用于调试的目的,由于不同于 JavaScript 有console.log() 函数,solidity 中是没有办法在 console 中打印出信息的。
代码如下:

  

  现在我们将添加布局函数,在 Solidity 中,它与我们的合约具有相同的名称,并且在创建合约时只调用一次。
在这里,第一位参与者将是创造合约的人。
msg.sender是调用该函数的人的地址。

  

  接下来,我们让另一个参与者利用以下函数进行注册:

 

  Require 函数是 Solidity 中一个分外的缺点处理函数,如果条件不知足,它会回滚变动。
在我们的示例中,如果变量参与者2即是0x0地址(地址即是0),我们可以连续;如果参与者2的地址与0x0地址不同,这就意味着某个玩家已经注册为对手,以是我们会谢绝新的注册。
可以把它认为是 solidity 中的if() {} else{}条件判断。

  再次强调,msg.sender是调用该函数的帐户地址,并且当我们触发一个事宜,就标志着角力的开始。

  现在,每一个参与者都会调用一个函数, wrestle(),并投入资金。
如果双方已经玩过这场游戏,我们就能知道个中一方是否得胜(我们的规则是个中一方投入的资金必须是另一方的双倍)。
关键字payable意味着函数可以吸收资金,如果它不是凑集,函数则不会接管币。
msg.value是发送到合约中的币的数量。

 

  请把稳,我们不是直接把钱交给赢家,在此情形下这并不主要,由于赢家会把该合约所有的钱提取出来;而在其他情形下,当多个用户要把合约中的以太币提取出来,利用withdraw模式会更安全,可以避免重入,在合约安全部分我们会详细谈论这些情形。

  大略地说,如果多个用户都可以从合约中提取资金,那么任谁都能一次性多次调用withdraw函数并多次得到报酬。
以是我们须要以这样一种办法来编写我们的取款功能:在他连续得到报酬之前,他应得的数额会作废。

  它看起来像这样:

 

  https://github.com/devzl/ethereum-walkthrough-1/blob/master/Wrestling.sol 有代码段。

  智能合约的IDE

  在区块链技能中,不仅转账是一笔交易,对合约中函数的调用和合约的支配都因此发送交易的办法完成。
全体过程比较繁琐,正犹如其他的变成措辞一样,针对付 solidity 智能合约,我们也供应了 IDE (CITA IDE) 来编译和支配合约。

  CITA 的IDE

  CITA IDE 是基于 Ethereum 的 Solidity 编辑器进行修正并适配了 CITA ,是面向 CITA 的智能合约编辑器,能够编写、编译、debug、支配智能合约。
可直接运行官方 CITA IDE 1(https://cita-ide.citahub.com)进行体验。

  利用解释

  browser 内置常用的模板合约,首先从内置合约模板中选择得当的模板开始开拓Compile 本地编译,选择当前 solidity 版本,与合约 pragma 同等进入右侧的 Run 标签, 在 Deploy to CITA 中填入干系信息勾选 Auto ValidUntilBlock 则发送交易前会自动更新 validUntilBlock 字段勾选 store ABI on chain 则会在合约支配成功后将合约 ABI 存储到 CITA 上此处特殊把稳 Quota 的设置, 一样平常合约须要较多 Quota, 若 quota 不敷, 在交易信息打印的时候可以查看 Error Message 获知点击 Load Contracts 加载当前编译完成的合约, 并选择要支配的合约点击 Deploy to CITA 发起支配合约的交易不雅观察掌握台的输出, 交易详细信息会显示在掌握台上, 当流程结束时, 会输出身意营业 hash 和合约地址, 并且以链接形式支持到 Microscope 查看

  DApp 及智能合约开拓实例

  First Forever 是一个DApp demo,展示了在 CITA 上开拓一个最小可用的 DApp 的完全流程。

  FIrst Forever 地址:

  https://github.com/citahub/first-forever-demo/blob/develop/README-CN.md

  以下是区块链DApp的开拓步骤示意图:

  在该项目中利用了一个大略的可以存储用户提交内容的智能合约,源码:SimpleStore

  地址:

  https://github.com/citahub/first-forever-demo/blob/develop/src/contracts/SimpleStore.sol

  更详细的先容看:如何动手做一个DApp

  地址:https://github.com/citahub/first-forever-demo/blob/develop/README-CN.md

  3

  智能合约安全性

  参考视频

  [https://www.bilibili.com/video/av58299098]

  由于智能合约是不可逆的,以是他的交易一旦形成,是无法回退的。
在这种环境下,智能合约的安全性尤为主要。
以下先先容几种合约常见的合约安全性隐患,然后会给出改进他们的方法。

  智能合约溢出型漏洞

  16bit 整数:0x0000,0x0001,0x0002,…,0xfffd,0xffff

  0x8000 + 0x8000 = 0x10000 = 0x0000 = 0

  0xffff + 0x0003 = 0x10002 = 0x0002 = 2

  0x0000 - 0x0001 = 0xffff = -1 = 65535

 

  这个函数想要做到的是把 msg.sender 在合约中的 token 转给多个人,amount += _value[j];这个操作会存在溢出的风险,如果在加的时候涌近况态 amount = 0x8000 + 0x8000 = 0,那么在后面一步的判断 require(balanceOf[msg.sender] >= amount);中会涌现的实际判断的是balanceOf[msg.sender] >= 0那么可以从空的账户中把钱转出。

  代码注入漏洞

 

  可以把这个合约本身拥有的代币偷走转给别的用户,由于对付extraData 来说,自由度非常高,_spender.call(_extraData)可以是任何一个地址调用任何一个函数。

  itchyDAOin MakerDAO 投票系统

  这个紧张因此一个比较繁芜的例子来给学员讲合约中函数调用须要知道的地方,暗示智能合约还是比较难以把控的,须要多学习

  以下是一个在 MakerDAO 中的投票系统,在这个投票系统中,一个sender 须要根据自己的权重对一个提案进行投票。

  

  以下是投票函数,在投票往后把票数进行 addWeight 和 subWeight 操作。

 

  末了一步是在 lock 一种币,在 lock 往后可以进行投票操作,在投票完成往后,可以 free 从而退回自己的币。

  

  4

  智能合约场景

  长远看,遵照标准有很多不应忽略的益处。
首先,如果遵照某个标准天生代币,那么每个人都会知道该代币的根本功能,并知道如何与之交互,因此就会有更多信赖。
去中央化程序(DApps)可以直接辨别出其代币特色,并通过特定的 UI 来与其打交道。
其余,一种代币智能合约的标准实现已经被社区开拓出来,它采取类似 OpenZeppelin 的架构。
这种实现已经被很多大神验证过,可以用来作为代币开拓的出发点。

  本文中会从头开始供应一个不完全的,但是遵照 ERC20 标准的,根本版的代币实现,然后将它转换成遵照 ERC721 标准的实现。
这样就能让读者看出两个标准之间的不同。

  出发点是希望大家理解代币是如何事情的,其过程并不是一个黑箱;其余,对付 ERC20 这个标准,只管它至少已经被广泛接管两年以上,如果只是从标准框架大略地天生自己的代币,也还会存在某些不易创造的故障点。

  ERC20 标准

  ERC20(https://theethereum.wiki/w/index.php/ERC20_Token_Standard)是为同质(Fungible)代币标准设立的标准,可以被其它运用(从钱包到去中央化交易所)重复利用。
同质意味着可以用同类的代币互换,换句话说,所有的代币都是等价的(就像泉币,某一美金和其它美金之间没有差异)。
而一个非同质代币(Non-fungible Token)代表一种特定价值(例如房屋,财产,艺术品等)。
同质代币有其内在代价,而非同质代币只是一种代价智能合约的代表。

  要供应符合ERC20标准的代币,须要实现如下功能和事宜:

  

  标准不供应功能的实现,这是由于大家可以用自己喜好的办法写出任何代码,如果不须要供应某些功能只须要按照标准(https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)返回 null/false 的值就可以了。

  把稳:这里并不很强调代码,大家只需理解内部机理,全部代码将会在文末附上链接。

  实现

  首先,须要给代币起一个名字,因此会采取一个公有变量(Public Variable):

  string public name = “Our Tutorial Coin”;

  然后给代币起一个代号:

  string public symbol = “OTC”;

  当然还要有详细小数位数:

  uint8 public decimals = 2;

  由于 Solidity 并不完备支持浮点数,因此必须把所有数表示成整数。
例如,对付一个数字 “123456”,如果利用 2 位小数,则代表 “1234.56”;如果采取4位小数,则代表 “12.3456”。
0 位小数代表代币不可分。
而以太坊的加密币以太币则利用18位小数。
一样平常地,代币不须要利用18位小数,由于遵照了以太坊的老例,也没有什么特殊的目的。

  你须要统计一共发行了多少代币,并跟踪每人拥有多少:

 

  当然,你须要从0个代币开始,除非在代币智能合约创建时候就天生了一些,如下例:

  

  totalSupply()函数只是从totalSupply变量中获取数值:

 

  接下来便是ERC20的神奇之处了,transfer()函数是将代币从一个地址发送到其余一个地址的函数:

  

  以上基本便是 ERC20 代币标准的核心内容。

  鉴于 ERC20 还存在其他一些问题,更安全容错的transferFrom()实现和其它方案被发布出来(如之前所说,该标准只是一些功能原型和行为定义,详细细节则靠开拓者自己实现),并正在谈论中,个中就包括

  ERC223(https://github.com/ethereum/EIPs/issues/223)ERC777(https://github.com/ethereum/EIPs/issues/777)

  ERC223 方案的动机是避免将代币发送到缺点地址或者不支持这种代币的合约上,成千上万的金钱由于上述缘故原由丢失,这一需求作为以太坊后续开拓功能的第 223 条记录第 223 条记录在案。
ERC777 标准在支持其它功能的同时,对吸收地址进行“即将收到代币”的提醒功能,ERC777 方案看起来很有可能替代 ERC20.

  ERC721标准

  ERC721目前看,ERC721 跟 ERC20 及其近亲系列有实质上的不同。
ERC721 中,代币都是唯一的。
ERC721 提出来后的浩瀚利用案例中,CryptoKitties,这款利用ERC721标准实现的网络虚拟猫游戏使得它备受瞩目。
以太猫游戏实际便是智能合约中的非同质代币 (non-fungible token),并在游戏中用猫的形象来表现出来。

  如果想将一个 ERC20 合约转变成 ERC721 合约,我们须要知道 ERC721 是如何跟踪代币的。
在 ERC20 中,每个地址都有一个账目表,而在 ERC721 合约中,每个地址都有一个代币列表:

  mapping(address => uint[]) internal listOfOwnerTokens;

  由于 Solidity 自身限定,不支持对行列步队进行 indexOF()的操作,我们不得不手动进行行列步队代币跟踪:

  mapping(uint => uint) internal tokenIndexInOwnerArray;

  当然可以用自己实现的代码库来创造元素的索引,考虑到索引韶光有可能很长,最佳实践还是采取映射办法。

  为了更随意马虎跟踪代币,还可以为代币的拥有者设置一个映射表:

  mapping(uint => address) internal tokenIdToOwner;

  以上便是两个标准之间最大的不同,ERC721 中的 transfer()函数会为代币设置新的拥有者:

  

  只管代码比较长,但却是转移代币流程中必不可少的步骤。

  还必须把稳,ERC721 也支持approve()和transferFrom()函数,因此我们必须在 transfer 函数内部加上其它限定指令,这样一来,当某个代币有了新的拥有者,之前的被授权地址就无法其代币进行转移操作,代码如下:

  

  挖矿基于以上两种标准,可能面对同一种需求,要么产生同质代币,要么产生非同质代币,一样平常都会用一个叫做Mint()的函数完成。

  实现以上功能函数的代码如下:

  

  用任意一个数字产生一个新代币,根据不同运用处景,一样平常在合约内部只会授权部分地址可以对它进行铸币(mint)操作。

  这里须要把稳mint()函数并没有涌如今协议标准定义中,而是我们添加上去的,也便是说我们可以对标准进行扩充,添加其它对代币的必要操作。
例如,可以添加用以太币来买卖代币的系统,或者删除不再须要代币的功能。

来源:溪塔科技

原文链接:https://mp.weixin.qq.com/mp/homepage?__biz=MzI4ODk4ODYxMg==&hid=9&sn=5cc5e3128a9a43495aa76d3a17a70073&scene=25#wechat_redirect

本文来自互联网,如有侵权请与我们联系删除。

标签:

相关文章

php反射机制应用技巧_php反射机制用法详解

面向工具编程中工具被授予了自省的能力,而这个自省的过程便是反射。反射,直不雅观理解便是根据到达地找到出发地和来源。比如,一个光秃秃...

Web前端 2024-12-13 阅读0 评论0