相关文章推荐
坚韧的皮蛋  ·  邮储银行落地行内首笔基于数字人民币智能合约的 ...·  10 月前    · 
坚韧的皮蛋  ·  “元管家”“无障碍”设计等多个成果亮相数字人 ...·  10 月前    · 
坚韧的皮蛋  ·  广州落地全国首个基于数字人民币智能合约的医疗 ...·  10 月前    · 
坚韧的皮蛋  ·  智能合约与数字人民币·  10 月前    · 
坚韧的皮蛋  ·  数字人民币场景创新提速-新华网·  10 月前    · 
小百科  ›  以太坊智能合约的原理和使用方法_cactusblossom的博客
智能合约 智能合约 函数调用 以太坊
爱笑的热带鱼
3 年前
  • 一、智能合约概述
    • 1.1 智能合约是什么
    • 1.2 solidity语言
  • 二、外部账户调用智能合约
  • 三、一个合约调用另一个合约
    • 3.1 直接调用
    • 3.2 使用address类型的call()函数
    • 3.3 代理调用delegatecall()函数
    • 3.4 payable
    • 3.5 fallback()函数
  • 四、智能合约的创建和运行
    • 4.1 创建与运行
    • 4.2 汽油费(gas fee)
    • 4.3 错误处理
    • 4.4 嵌套调用
  • 五、智能合约可以获取的信息
    • 5.1 区块信息
    • 5.2 合约调用信息
  • 六、合约地址类型
    • 6.1 合约地址调用
    • 6.2 转账给合约

    一、智能合约概述

    1.1 智能合约是什么

    智能合约本质上是运行在区块链上的一段代码,代码的逻辑定义了合约的内容。
    智能合约账户保存了合约当前的运行状态,包括当前余额(balance)、交易次数(nonce)、合约代码(code)、存储(storage 数据结构是MPT,合约的执行数据保存在这里)。

    1.2 solidity语言

    智能合约的最常用的语言是Solidity,语法上与JavaScript很接近。如下图所示:
    在这里插入图片描述
    “pragma solidity ^0.4.21”声明solidity版本号,不同版本在语法上有一些差别;
    contract相当于“class(类)”,里面定义了一些状态变量。solidity是强类型编程语言,大部分类型与常用编程语言类似,address类型是solidity特有的类型;
    mapping哈希表不支持遍历,所以需要单独创建一个数组,用于遍历key值,例如上图的哈希表bids和数组bidders;
    event(事件)用于记录日志,使用emit调用该日志函数;
    constructor是构造函数,仅在合约创建时调用一次;
    接下来3个成员函数都是public,可以被外部账户或合约账户调用。

    二、外部账户调用智能合约

    如果外部账户是转账给另一个外部账户,那么与比特币的转账几乎相同;如果转账给合约账户,那么就是发起这个账户的合约调用,调用的函数及参数在“TX DATA”域中说明,如下图所示:
    在这里插入图片描述
    其它域的说明如下:
    “SENDER ADDRESS”为发起转账的地址;
    “TO CONTRACT ADDRESS”为接收的合约账户;
    “VALUE”为转账金额(金额为0说明仅调用函数,没有转账);
    “GAS USED”是该交易花费的汽油量;
    “GAS PRICE”是单位汽油的价格;
    “GAS LIMIT”为发起人最多愿意花费的汽油量。

    三、一个合约调用另一个合约

    一个合约可以调用另一个合约,但是合约账户不能主动调用另一个合约,必须由外部账户发起。

    3.1 直接调用

    给出另一个合约的地址,直接调用。如下图所示,callAFooDirectly的参数是一个合约地址,将地址转换为合约实例,然后就可以调用该合约的foo函数:
    在这里插入图片描述
    如果在执行a.foo()过程中抛出错误,则callAFooDirectly也抛出错误,本次调用全部回滚。ua为执行a.foo(“call foo directly”)的返回值。
    另外可以通过.gas() 和 .value() 调整提供的gas数量或提供一些ETH。

    3.2 使用address类型的call()函数

    通过address类型call函数调用智能合约。下面这个例子相当于A(addr).foo(“call foo by func call”),如下图所示:
    在这里插入图片描述
    call函数的第一个参数被编码成4个字节,表示要调用的函数的签名。其它参数会被扩展到32字节,表示要调用函数的参数。
    返回一个布尔值表明了被调用的函数已经执行完毕(true)或者引发 了一个EVM异常(false),无法获取函数返回值。而发起调用的函数并不会产生异常,继续执行。
    与直接调用类似,也可以通过.gas() 和 .value() 调整提供的gas数量或提供一些ETH。

    3.3 代理调用delegatecall()函数

    代理调用delegatecall()函数使用方法与call()相同,只是不能使用.value()。
    另外call()会切换到被调用的智能合约上下文中,delegatecall()只使用给定地址的代码,其它属性(存储,余额等)都取自当前合约。delegatecall 的目的是使用存储在另外一个合约中的库代码。

    3.4 payable

    如果合约账户接收外部转账(“VALUE”域不为0),被调用的函数必须标注payable。例如下图所示,bid函数接收拍卖出价,以太币存储在合约内,可以防止恶意出价:
    在这里插入图片描述

    3.5 fallback()函数

    如果转账交易的“TX DATA”域中没有说明函数名,或域里的函数名不存在,则默认调用fallback函数,如果合约中没有定义fallback函数(合约中不一定存在fallback函数),那么将调用失败。函数定义如下所示:
    function() public [payable]{
    ……
    }

    • 匿名函数,没有参数也没有返回值。
    • 如果转账金额(“VALUE”域)不是0,同样需要声明payable,否则会抛出异常。

    四、智能合约的创建和运行

    4.1 创建与运行

    智能合约的代码写完后,要编译成bytecode。创建合约时,外部帐户发起一个转账交易到0x0的地址,转账金额(“VALUE”域)是0,但是要支付汽油费,合约的代码放在data域里。

    智能合约运行在EVM(Ethereum Virtual Machine)上,EVM的寻找空间为256位。以太坊是一个交易驱动的状态机,调用智能合约的交易发布到区块链上后,每个矿工都会执行这个交易,从当前状态确定性地转移到下一个状态。

    4.2 汽油费(gas fee)

    智能合约是个Turing-complete Programming Model。理论上可证明,不存在任何算法可判断出任一程序是否会停机。
    以太坊中使用汽油费机制,防止出现死循环。合约中的指令在执行时要收取汽油费,由发起交易的人来支付。EVM中不同指令消耗的汽油费是不一样的,简单的指令很便宜,复杂的或者需要存储状态的指令就很贵读取。读取公共数据时,则不需要汽油费。汽油费在txdata结构体中,代码如下所示:
    在这里插入图片描述
    AccountNonce是交易序号,用于防止重放攻击,Price是单位汽油价格,GasLimit是愿意支付的最大汽油量,Recipient是收款人地址,Amount是转账金额,Payload是合约函数和参数,即前面章节所述的txDATA域。
    实际系统中,节点收到一个智能合约调用时,先按照GasLimit从发起的账户里扣掉Gas fee,增加自己账户余额,然后根据实际执行结果算出花费的汽油费,多出的汽油费会退还。如果执行中发现汽油费不足,会引起回滚,但是执行中扣掉的汽油费不会退还;

    GasLimit:
    区块头结构体中的GasUsed指的所有交易用的汽油总和;GasLimit指的是区块内所有交易能够消耗的汽油上限,与txData结构体中的GasLimit没有关系,用于限制区块内消耗的资源(比特币中使用区块小于1M来限制)。每个矿工在打包区块时,都可以在父区块的GasLimit基础上调整±1/1024。

    合约执行异常的汽油费
    合约执行过程中出现任何异常,都会回滚,同时扣掉对应汽油费,所以出错的交易也会包含在区块中。合约执行结果体现在交易收据中,即Receipt结构体中的Status域。
    其他节点收到区块后会扔掉自己的执行结果,同时验证区块内的交易,包括验证汽油费的扣除是否合法。然后更新本地数据结构,继续挖矿。

    4.3 错误处理

    智能合约的执行具有原子性,一旦遇到异常(比如汽油费不够),除特殊情况外,执行操作全部回滚,不会只执行一部分。智能合约中不存在自定义的try-catch结构,不可以捕获异常。
    可以抛出错误的语句如下:

    • assert(bool condition):如果条件不满足就抛出—用于内部错误。
    • require(bool condition):如果条件不满足就抛出—用于函数输入或者外部组件引起的错误。
    • revert():无条件地抛出异常,终止运行并回滚状态变动。

    4.4 嵌套调用

    嵌套调用是指一个合约调用另一个合约中的函数。如果被调用的合约执行过程中发生异常,有些调用方法会导致发起调用的这个合约也跟着一起回滚,而call()函数调用则不会连环回滚,只会使得当前调用失败,得到false返回值。

    一个合约直接向一个合约帐户里转账,没有指明调用哪个函数,仍然会引起嵌套调用,这时调用的是fallback函数。

    五、智能合约可以获取的信息

    智能合约不支持任何造成执行结果不确定的操作,比如多线程下对内存的访问、真随机数产生。
    另外智能合约无法获取与系统环境相关的信息,因为每个系统的环境都是不一样的,所以只能获得一些固定信息。

    5.1 区块信息

    智能合约可以获得的区块信息如下:

    • block.blockhash(uint blockNumber) returns (bytes32):获得指定区块的哈希,仅对最近256个区块有效而不包括当前区块
    • block.coinbase (address):挖出当前区块的矿工地址
    • block.difficulty (uint):当前区块难度
    • block.gaslimit (uint):当前区块gas限额
    • block.number (uint):当前区块号
    • block.timestamp (uint):自unix epoch起始当前区块以秒计的时间戳

    5.2 合约调用信息

    智能合约可以获得的合约调用信息如下:

    • msg.data (bytes):完整的calldata
    • msg.gas (uint):剩余gas
    • msg.sender (address):消息发送者(当前调用)
    • msg.sig (bytes4):calldata的前4字节(也就是函数标识符)
    • msg.value (uint):随消息发送的wei的数量
    • now (uint):目前区块时间戳(block.timestamp)
    • tx.gasprice (uint):交易的gas价格
    • tx.origin (address):交易发起者(完全的调用链)

    六、合约地址类型

    6.1 合约地址调用

    所有智能合约均可显式地转换成地址类型,当前智能合约得到另一个合约的address,便可通过address调用对应合约的成员变量和函数,如下所示:

    • <address>.balance (uint256):
      balance为成员变量,类型是uint256,以Wei为单位的地址类型的余额;
    • <address>.call(…) returns (bool):
      发出底层call,失败时返回false,发送所有可用gas,不可调节;
    • <address>.callcode(…) returns (bool):
      发出底层callcode,失败时返回false,发送所有可用gas,不可调节;
    • <address>.delegatecall(…) returns (bool):
      发出底层delegatecall,失败时返回false,发送所有可用gas,不可调节。

    6.2 转账给合约

    转账给合约地址方式如下所示:

    • <address>.transfer(uint256 amount):
      会触发调用fallback函数,向地址类型发送数量为amount的Wei,失败时抛出异常,同时发送2300gas的矿工费,不可调节;
    • <address>.send(uint256 amount) returns (bool):
      会触发调用fallback函数,向地址类型发送数量为amount的Wei,失败时返回fasle,同时发送2300gas的矿工费用,不可调节;
    • <address>.call.value(uint256 amount)():
      会触发调用fallback函数,向地址类型发送数量为amount的Wei,失败时返回fasle,发送所有可用gas,多余的gas再返回。
    一、智能合约概述1. 智能合约是什么智能合约本质上是运行在区块链上的一段代码,代码的逻辑定义了合约的内容。智能合约账户保存了合约当前的运行状态,包括当前余额(balance)、交易次数(nonce)、合约代码(code)、存储(storage 数据结构是MPT)。2. solidity语言智能合约的最常用的语言是Solidity,语法上与JavaScript很接近。如下图所示:“pr... 3、 智能合约 的数据类型和dapp web3的合约创建及调用 4、 以太坊 solidity结构化存储类型和dapp 合约数组调用 5、 以太坊 solidity变量 使用 和dapp 智能合约 事件交互 使用 6、 以太坊 solidity函数的语法及调用和dapp 超大数字 使用 7、 以太坊 solidity合约间调用等控制结构和...
    智能合约 主要有两大方面的作用,一个是用于更便捷地处理交易,一个适用于更灵活的开发的APP,也就是 区块链 应用。 以太坊 虚拟机:虚拟机是计算机领域里面的一个术语,可以理解为一个虚拟环境,在这个虚拟环境中可以随意进行 操作 ,而不影响计算机的性能, 以太坊 本质上就是一个虚拟机,只不过它是一个点对点的去中心化的虚拟机。像所有 区块链 技术那样,全世界的节点都会在自己的电脑上运行软件,这个包含全世界节点的世界级计算机就被称为 以太坊 虚拟机。 以太坊 虚拟机我们可以理解为一个系统,这个系统是用来为 以太坊 智能合约 创建运行环境的。以
    以太坊 基本 原理 包括: 以太坊 账户、 以太坊 虚拟机、钥匙文件、交易、Gas、 以太坊 区块、以太币 以太坊 开发包括: 以太坊 客户端, 以太坊 钱包,搭建 以太坊 私有链, 智能合约 ,redmix-ide开发 智能合约 1. 以太坊 基本 原理 1.1 以太坊 简介 以太坊 是一个开源的有 智能合约 功能的公共 区块链 平台,它提供了一个虚拟机来处理点对点的合约。 以太坊 概念最早是由Vitalik Buterin在2013年到2014年被提出的,2014年通过ICO众筹开始得以发展 以太坊 的本质就是一个状态机(读取输入并且输出) 相比 比特币 的10分钟产
    remix小demo https://remix.ethereum.org 目前尝试 Solidity 编程的最好方式是 使用 Remixo Remix 是一个基于浏览器的 Solidity IDE , 它集成了 Solidity 编译器、运行环境 ,以及调试和发布工具。 使用 浏览器打开网址 https://remix.ethereum.org 官方demo // SPDX-Lic 创建 智能合约 以太坊 中的 智能合约 是运行在 区块链 上的一段代码,代码的逻辑定义了合约的内容。只能合约是 以太坊 和 比特币 系统最大的区别。在 以太坊 中, 智能合约 的账户保存了合约当前的运行状态,主要包含了4部分内容。 balance:当前余额 nonce: 交易次数 code: 合约代码 storge: 存储,是一棵MPT 智能合约 一般... 以太坊 智能合约 基于 区块链 (Blockchain)技术,作为一种旨在以信息化方式传播、验证或执行的计算机协议,为各类分布式应用服务提供了基础。简单来讲:如果把 比特币 看作是分布式的记账本; 以太坊 便是可以运行程序的分布式计算平台,程序运行的基础则是Solidity 智能合约 。 智能合约 早在1995年就由尼克萨博提出,
    文章目录一、安装Web3.js二、连接geth节点三、编写和编译 智能合约 四、发布 智能合约 五、调用 智能合约 六、自动编译 智能合约 一、安装Web3.js   Web3.js是一套用Javascript实现的API,用于与 以太坊 节点进行通信,并通过 以太坊 节点 操作 以太坊 网络。Web.js内部 使用 JSON-RPC协议与 以太坊 节点(geth和其他类型的节点)进行通信。   JSON-RPC是一个无状态且轻量级...
    正如我们在之前的文章中所讨论的, 智能合约 交易类似于 智能合约 驱动的web3应用程序中的后端API调用。每个 智能合约 交易和结果应用程序状态更改的细节都记录在称为交易、调用和日志的数据元素中。交易数据元素表示用户发起的函数调用(更准确地说是EOA),调用数据元素表示 智能合约 在交易中发起的其他函数调用,而日志数据元素表示交易执行期间发生的事件。 使用 这些数据元素,可以非常精细地描述由于交易而在应用程序和 区块链 上发生的状态更改。当对一个去中心化的web3应用程序的所有交易、跟踪和日志进行汇 1. 什么是 智能合约 从技术角度来说, 智能合约 可以看作一种计算机程序,这种程序可以自主地执行全部或部分和合约相关的 操作 ,并产生相应的可以被验证的证据,来说明执行合约 操作 的有效性。 智能合约 允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。 简单理解的话,你可以把自动售货机看成一个销售商品的 智能合约 ,执行的就是你和机器主人之间关于如何购买一瓶饮料的合约。
 
推荐文章
坚韧的皮蛋  ·  邮储银行落地行内首笔基于数字人民币智能合约的供应链金融服务
10 月前
坚韧的皮蛋  ·  “元管家”“无障碍”设计等多个成果亮相数字人民币走入千家万户
10 月前
坚韧的皮蛋  ·  广州落地全国首个基于数字人民币智能合约的医疗采购资金结算场景
10 月前
坚韧的皮蛋  ·  智能合约与数字人民币
10 月前
坚韧的皮蛋  ·  数字人民币场景创新提速-新华网
10 月前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
小百科 - 百科知识指南
© 2024 ~ 沪ICP备11025650号