介绍
简单地说,一个现实世界的合同是一个管理行动结果的协议,给定一组输入。合同的范围可以从正式的法律合同(例如,金融交易)到诸如游戏的“规则”之类的简单。典型的行为可以是诸如资金转移(在金融合同的情况下)或游戏移动(在游戏合同的情况下)的事情。
EOSIO智能合约是在区块链上注册并在EOSIO节点上执行的软件,它实现了“合同”的语义,其合约行动请求的分类帐存储在区块链中。智能合约定义了接口(操作,参数,数据结构)和实现接口的代码。代码被编译成规范的字节码格式,节点可以检索和执行。区块链存储合同的交易(例如,合法转移,游戏移动)。每份智能合约都必须附有一份李嘉图合同,该合同定义了合同中具有法律约束力的条款和条件。
所需知识
C / C ++经验
基于EOSIO的区块链使用WebAssembly(WASM)执行用户生成的应用程序和代码。WASM是一种新兴的Web标准,得到了Google,Microsoft,Apple和其他公司的广泛支持。目前,用于构建编译为WASM的应用程序的最成熟的工具链是clang / llvm及其C / C ++编译器。为获得最佳兼容性,建议您使用EOSIO工具链。
第三方开发的其他工具链包括:Rust,Python和Solidity。虽然这些其他语言可能看起来更简单,但它们的性能可能会影响您可以构建的应用程序的规模。我们希望C ++将成为开发高性能和安全智能合约的最佳语言,并计划在可预见的未来使用C ++。
Linux / Mac OS体验
EOSIO软件支持以下环境:
- 亚马逊2017.09及更高
- Centos 7
- Fedora 25及更高版本(Fedora 27推荐)
- Ubuntu 16.04(Ubuntu 16.10推荐)
- Ubuntu 18.04 LTS
- MacOS Darwin 10.12及更高版本(建议使用MacOS 10.13.x)
命令行知识
EOSIO提供了各种工具,要求您具备基本的命令行知识才能与之交互。
沟通模式
EOSIO智能合约由一组操作和类型定义组成。操作定义指定并实现合同的行为。类型定义指定所需的内容和结构。EOSIO操作主要在基于消息的通信体系结构中运行。客户端通过发送(推送)消息来调用操作nodeos
。这可以使用cleos
命令完成。它也可以使用EOSIO send
方法之一(例如eosio::action::send
)完成。nodeos
将操作请求分派给实现合同的WASM代码。该代码完整运行,然后继续处理下一个操作。
EOSIO智能合约可以相互通信,例如,让另一个合同执行与当前交易完成相关的某些操作,或触发当前交易范围之外的未来交易。
EOSIO支持两种基本通信模型,内联和延迟。在当前事务中执行的操作是内联操作的示例,而触发的将来事务是延迟操作的示例。
合同之间的沟通应视为异步发生。异步通信模型可能导致垃圾邮件,资源限制算法将解析垃圾邮件。
内联通讯
内联通信采用请求其他操作的形式,这些操作需要作为调用操作的一部分执行。内联操作使用原始事务的相同作用域和权限进行操作,并保证使用当前事务执行。这些可以有效地被认为是调用事务中的嵌套事务。如果事务的任何部分失败,则内联操作将与事务的其余部分一起展开。无论成功与否,调用内联操作都不会在事务范围之外生成任何通知。
延期沟通
延迟通信在概念上采用发送到对等事务的动作通知的形式。根据生产者的判断,延迟的操作最多可以安排在稍后的时间运行。无法保证将执行延期操作。
如前所述,延迟通信将由生产者自行决定。从原始事务的角度来看,即创建延迟事务的事务,它只能确定创建请求是否已成功提交或是否失败(如果失败,则会立即失败)。延期交易具有发送它们的合同的权限。交易可以取消延期交易。
交易VS. 操作
动作表示单个操作,而事务是一个或多个动作的集合。合同和帐户以行动的形式进行沟通。如果要将操作作为一个整体执行,则可以单独发送操作,也可以以组合形式发送操作。
交易只有一个动作。
{
"expiration": "2018-04-01T15:20:44",
"region": 0,
"ref_block_num": 42580,
"ref_block_prefix": 3987474256,
"net_usage_words": 21,
"kcpu_usage": 1000,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio.token",
"name": "issue",
"authorization": [{
"actor": "eosio",
"permission": "active"
}
],
"data": "00000000007015d640420f000000000004454f5300000000046d656d6f"
}
],
"signatures": [
""
],
"context_free_data": []
}
具有多个操作的事务,这些操作必须全部成功或事务将失败。
{
"expiration": "...",
"region": 0,
"ref_block_num": ...,
"ref_block_prefix": ...,
"net_usage_words": ..,
"kcpu_usage": ..,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "...",
"name": "...",
"authorization": [{
"actor": "...",
"permission": "..."
}
],
"data": "..."
}, {
"account": "...",
"name": "...",
"authorization": [{
"actor": "...",
"permission": "..."
}
],
"data": "..."
}
],
"signatures": [
""
],
"context_free_data": []
}
无上下文行为
行动名称限制
动作类型实际上是base32编码的64位整数。这意味着它们仅限于字符az,1-5和'。' 对于前12个字符。如果有第13个字符,则它被限制为前16个字符('。'和ap)。
有关更多详细信息,请参阅此处的链接
交易确认
交易完成后,将生成交易收据。此收据采用散列形式。接收事务散列并不意味着事务已被确认,它只意味着节点接受它而没有错误,这也意味着其他生产者很可能会接受它。
通过确认,您应该在事务历史记录中看到包含它的块编号的事务。
操作处理程序和操作“应用”上下文
智能合约提供操作处理程序来执行所请求操作的工作。(有关此内容的更多信息)每次操作运行时,即通过apply
在合同实现中运行方法“应用”操作,EOSIO会创建一个新的操作“应用”上下文,操作在该上下文中运行。下图说明了“应用”上下文操作的关键元素。
从EOSIO区块链的全局视图来看,EOSIO网络中的每个节点都会获得每个合同中的每个操作的副本并运行。一些节点正在执行合同的实际工作,而其他节点正在处理以证明事务块的有效性。因此,重要的是合同能够确定“他们是谁”,或者基本上,他们在哪个环境下运行。上下文识别信息在动作上下文中提供,如上述图所示receiver
,code
,action
。receiver
是当前正在处理操作的帐户。code
是授权合同的帐户。action
是当前正在运行的操作的ID。
如上所述,行动在交易中运作; 如果事务失败,则必须回滚事务中所有操作的结果。动作上下文的关键部分是当前交易数据。这包含事务头,事务中所有原始操作的有序向量,事务中上下文自由操作的向量,由代码定义的可修复的上下文无关数据集(作为blob的向量提供)实现契约,以及blob向量的完整索引。
在处理操作之前,EOSIO会为操作设置一个干净的工作内存。这是保持动作的工作变量的地方。操作的工作内存仅对该操作可用,即使对于同一事务中的操作也是如此。在执行另一个操作时可能已设置的变量在另一个操作的上下文中不可用。在操作之间传递状态的唯一方法是将其持久化并从EOSIO数据库中检索它。有关如何使用EOSIO持久性服务的详细信息,请参阅Persistence API。
动作可能有许多副作用。其中包括:
- 更改状态在EOSIO持久存储中保持不变
- 通知当前交易的收件人
- 将内联操作请求发送给新接收方
- 生成新的(延期)交易
- 取消现有(在飞行中)延期交易(即取消已提交的延期交易请求)
交易限制
每个事务必须在30ms或更短时间内执行。如果事务包含多个操作,并且这些操作的总和大于30毫秒,则整个事务将失败。在没有对其操作进行并发性要求的情况下,可以通过在单独的事务中包含CPU使用操作来规避这种情况。