首页 > 其他分享 >eosio.system智能合约介绍(四)合约部署介绍

eosio.system智能合约介绍(四)合约部署介绍

时间:2023-09-14 13:02:34浏览次数:40  
标签:account abi addressbook system ABI table eosio 合约

01

目的

本文档结合系统合约,介绍了合约部署的核心概念和步骤,包括合约部署过程以及setcode和setabi方法,帮助初学者和开发者快速了解和掌握EOS系统合约部署的相关知识。

02

概述

“eosio.system”智能合约是eos的系统命令合约。这个合约几乎实现了eos全部的系统命令,包括创建账户、资源质押、超级节点投票、域名竞拍等功能,它定义了区块链核心功能所需的结构和操作。

下文将介绍合约部署的相关知识。

03

环境准备

(一)一条正在运行且可访问的区块链

中移链(基于EOS)测试环境搭建

(二)确保本地钱包已打开并解锁

如何创建钱包:

https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-create-a-wallet

04

合约部署介绍

(一)合约部署过程

假设您要将合约部署到的帐户名称是addressbook,请执行以下命令:

cleos set contract addressbook you_local_path_to/addressbook/ -p addressbook@active

命令详解:

set contract:cleos 工具的子命令,用于部署合约

addressbook:要部署合约的账户名称,即目标账户。请将 addressbook 替换为您自己的账户名称

you_local_path_to/addressbook/:合约的本地路径,指定了合约的位置。请将 /your_local_path_to/替换为您本地的实际路径,最好是绝对路径

-p addressbook@active:指定操作的权限。在这种情况下,-p参数后面的addressbook表示使用 addressbook 账户的active权限进行操作。请确保addressbook账户具有足够的权限来部署合约

通过运行这个命令,合约将被部署到addressbook账户。

得到如下结果:

Reading WASM from /home/xxx/biosboot/genesis/test/addressbook/addressbook.wasm...
Publishing contract...
executed transaction: ea09081dc5e42bd1f2b5abe619a7388e1e52ec16a91adb221f3ecb11fa566dde  17840 bytes  16689 us
#         eosio <= eosio::setcode               {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d01000000019a022a60000060037f7f7f01...
#         eosio <= eosio::setabi                {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e32000305657261736500010475736572046e616d...

部署EOSIO合约时,需经历以下步骤:

  • 读取WAST/WASM文件:读取存放在build目录下的WAST/WASM文件,这些文件是要部署的合约的编译结果;
  • 装配WASM:对于读取的WAST/WASM文件,进行装配,将合约的二进制代码准备好供后续操作使用。
  • 将合约发布到区块链上
  • 执行交易(合约也是一个交易),需要执行两个关键动作:
  • setcode:该动作用于在区块链上部署或更新账户的合约代码。
  • setabi:该动作用于为通过account名称标识的合约设置ABI(ApplicationBinaryInterface)。尽管在技术上ABI是可选的,但所有EOSIO工具都依赖于它以提供更便捷的合约交互体验。

执行完以上操作后,合约已成功部署到EOS区块链中的addressbook账户上。

从结果可以看出,调用

cleossetcontractaddressbookyou_local_path_to/addressbook/-paddressbook

等价于调用:

cleos push action addressbook setcode '[addressbook.wasm]' -p addressbook
cleos push action addressbook setabi '[addressbook.abi]' -p addressbook

(二)setcode方法介绍

setcode操作是EOSIO中的一种操作,用于在区块链上部署或更新账户的合约代码。它用于部署或更新与账户关联的智能合约。在使用setcode操作部署或更新合约时,会检查合约是否已经在运行代码。

具体而言,当执行setcode操作时,EOSIO会获取合约的wasm文件,并对其进行处理。在处理过程中,会计算wasm文件的哈希值,以表示该合约的唯一标识。这个哈希值可以用于比对合约的版本和完整性,以确保在部署或更新合约时没有出现错误或篡改。

1、setcode源码介绍

/**
* Set code action sets the contract code for an account.
*
* @param account - the account for which to set the contract code.
* @param vmtype - reserved, set it to zero.
* @param vmversion - reserved, set it to zero.
* @param code - the code content to be set, in the form of a blob binary..
*/
[[eosio::action]]
void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector<char>& code ) {}

参数详解:

account:要部署或更新代码的账户名称

vmtype:此参数保留,应设置为零

vmversion:此参数保留,应设置为零

code:合约代码的二进制表示

2、setcode操作的实现

读取合约的WAST或WASM文件:

合约的开发人员提供合约代码的文件,这可以是WAST(WebAssemblyText)或WASM(WebAssemblyBinary)格式。

装配合约代码:

读取的合约文件需要进行装配,即将其转换为内部可执行的格式,以便区块链节点能够理解和执行。

存储合约代码:

装配后的合约代码将被存储在区块链上,并与指定的账号关联起来。这样,当其他用户或合约需要调用该合约时,可以通过发送交易指向该账号,并执行相应的合约操作。

通过setcode操作,合约的代码被安全地存储在区块链上,并与账号关联。这样,所有参与者都可以通过调用合约的操作来执行合约的功能,而节点可以验证合约的代码哈希值,确保合约的代码没有被篡改,从而保障合约在执行过程中的安全性和可靠性。

(三)setabi方法介绍

setabi操作用于为通过account名称标识的合约设置ABI(ApplicationBinaryInterface)。它在abi_hash_table索引中创建一个条目,使用account名称作为键,如果尚不存在,并将其值设置为ABI的哈希值。如果已存在,则更新现有account键的当前ABI哈希值。

1、setabi源码介绍

源码:

/**
          * Set abi action sets the abi for contract identified by `account` name. Creates an entry in the abi_hash_table
          * index, with `account` name as key, if it is not already present and sets its value with the abi hash.
          * Otherwise it is updating the current abi hash value for the existing `account` key.
          *
          * @param account - the name of the account to set the abi for
          * @param abi     - the abi hash represented as a vector of characters
          */
         [[eosio::action]]
         void setabi( name account, const std::vector<char>& abi )
{
           abi_hash_table table(get_self(), get_self().value);
           auto itr = table.find( account.value );
           if( itr == table.end() ) {
              table.emplace( account, [&]( auto& row ) {
                 row.owner = account;
                 row.hash  = eosio::sha256(const_cast<char*>(abi.data()), abi.size());
              });
           } else {
              table.modify( itr, eosio::same_payer, [&]( auto& row ) {
                 row.hash = eosio::sha256(const_cast<char*>(abi.data()), abi.size());
              });
           }
        }

参数详解:

account:要部署ABI的目标账户的名称。它是一个name类型的参数,表示EOSIO中的账户名

abi:要设置的合约的ABI数据,以std::vector<char>类型的参数传入

源码详解:

  • 通过abi_hash_table类创建一个名为table的表对象。该表用于存储账户的abi哈希值。
  • 使用table.find()函数查找表中是否已经存在与目标账户相关的记录。
  • 如果在表中没有找到与目标账户相关的记录(即itr==table.end()),则执行table.emplace()操作。
  • 在table.emplace()中,通过lambda表达式将新的记录插入到表中。lambda表达式接收一个row参数,用于访问新插入的记录。在lambda表达式中,将row.owner设置为目标账户的名称,将row.hash设置为传入的ABI数据的SHA256哈希值。
  • 如果在表中找到了与目标账户相关的记录(即itr!=table.end()),则执行table.modify()操作。
  • 在table.modify()中,通过lambda表达式修改找到的记录。这里使用eosio::same_payer权限,确保修改操作的付款账户与原始记录的付款账户相同。在lambda表达式中,将row.hash更新为传入的ABI数据的SHA256哈希值。

ABI的实际存储方式在EOSIO中与常见的JSON文件存储方式存在较大的差异。相反,ABI被以一种被称为"原始ABI"的打包方式进行存储。

传统的开发环境中通常将ABI表示为JSON格式的文件,其中包含了合约的接口和数据结构定义。然而,在EOSIO中为了减少存储空间和提高效率,ABI被以一种更紧凑的格式进行存储。

“原始ABI”是指将ABI数据按照一定的规则进行打包和编码,以减少其存储空间。这种打包方式不同于常见的JSON文件格式,它更加紧凑,节省了存储空间,并提高了读取和解析的效率。原始ABI存储方式在EOSIO中被使用,以满足区块链中存储资源的限制和性能需求。

每个ABI都需要包含一组特定的字段,这些字段用于描述合约的不同方面,如版本信息、类型定义、结构定义、操作定义、表格定义等。这些字段的内容将被序列化为一种更节省空间的表示形式。

在EOSIO中,ABI用于定义合约的接口和数据结构。为了方便存储和传输,ABI需要被序列化为一种紧凑的二进制格式,以节省存储空间和网络带宽。

具体而言,一个典型的ABI包含以下字段:

version:ABI的版本信息,用于标识ABI的兼容性和支持的特性

types:类型定义,用于描述合约中使用的自定义类型,如结构体、枚举等

structs:结构定义,描述合约中的数据结构,包括结构体的名称、字段和类型等

actions:操作定义,描述合约中可执行的操作,包括操作的名称、参数和返回类型等

tables:表格定义,描述合约中的数据表格,包括表格的名称、字段和索引等

当执行setabi操作时,合约的ABI数据可以以两种形式之一进行提供:二进制文件或JSON文件。二进制文件是指以二进制格式存储的ABI数据文件,而JSON文件则是指以JSON格式存储的文本文件。

setabi操作需要能够处理这两种形式的ABI数据,并进行相应的转换。具体而言,它可以将二进制文件转换为JSON格式的ABI数据,或将JSON格式的ABI数据转换为二进制格式,即序列化和反序列化的过程。这样,合约开发人员可以选择以更适合他们的方式提供ABI数据,并将其转换为适合在区块链上存储和使用的形式。

END

标签:account,abi,addressbook,system,ABI,table,eosio,合约
From: https://blog.51cto.com/u_15476243/7469053

相关文章

  • system_stm32f4xx.c文件配置时钟
    staticvoidSetSysClock(void){/******************************************************************************//*PLL(clockedbyHSE)usedasSystemclocksource*//***********************************************************......
  • systemd病毒遏制流程参考
    systemd挖矿病毒遏制流程参考top查看进程占用情况systemctlstatus128724找出占用较高的恶意进程的相关进程killSTOP128724121095停止对应恶意PID进程,为服务器CPU降压(注:这里不推荐直接删除进程,因为挖矿往往存在定时任务,删除后还会自动生成,但停止恶意进程会使其陷......
  • System.OutOfMemoryException:“Exception_WasThrown”
    32位4g内存吃满了,改64位重新编译,我这个程序的问题32位程序,最大只能用4G内存,但实机需要远超4G,内存不足就会报这种错误  ......
  • win2003系统system占用80端口的解决办法
    本人一直都是用APMServ在winxp中搭建本地服务器测试网站,但最近换了win2003系统,结果本来在XP正常使用的APMServ启动时死活都提示80端口被占用,换成8080端口,虽然提示服务启动了,但是本地网站却打不开,在cmd中用命令查找时,发现提示system占用了80端口。如何查看端口在win03的cmd命令窗口......
  • 80端口被system 占用解决方法
    今天启动Apache的时候老是提示失败,很简单,使用netstat-ano发现80端口被占用。如图所示: 按照PID来说:在任务管理器中查看PID的进程名 既然是system。那么应该不回是真正的系统。而是微软的其他系列产品的进程在运行。【注意:我已经在服务services.msc中结束了IISADmin服务......
  • JDBC 连接 MySQL 报错 Unknown system variable ‘query_cache_size‘
    官方说法:ThequerycacheisdeprecatedasofMySQL5.7.20,andisremovedinMySQL8.0.Deprecationincludesquery_cache_size.querycache在MySQL5.7.20已经过时了,并且在MySQL8.0版本中被移除了。所以要更新mysql驱动版本<dependency><groupId>mysql</groupId......
  • Android9.0 SystemServerCrash问题总结
    设备在反复休眠唤醒后SystemServer挂掉背景:同事自测发现,当反复按压Power键后概率性出现系统挂掉的问题。分析过程查看系统log如下:12-0511:43:27.53015091759IWatchdog:CollectingBinderTransactionStatusInformation12-0511:43:29.70415091759EWatchdog:First......
  • Fabric 2.x 智能合约开发记录
    表象:Returnschemainvalid.requireditemsmustbeunique[recovered]虽然Fabricv2.2已经发布了很久了,但之前因为项目历史问题,一直使用的都是Fabricv1.4.8,所以智能合约也一直使用的都是github.com/hyperledger/fabric/core/chaincode/shim包。在合约开发过程中,我一般......
  • 深入解析Java中的数组复制:System.arraycopy、Arrays.copyOf和Arrays.copyOfRange
    当涉及到在Java中处理数组时,有许多方法可供选择,其中一些包括System.arraycopy()、Arrays.copyOf()和Arrays.copyOfRange()。这些方法允许您在不同的数组之间复制数据,但它们之间有一些细微的差异。在本篇博客文章中,我们将深入探讨这些方法,以便您了解何时使用它们以及如何正确使用它......
  • Java系统变量参数 获取 设置 System.getProperties()
    目录1.获取2.设置3.常用参数4.Systm.getenv()与System.getProperties()区别1.获取 StringosName=System.getProperties().getProperty("os.name"); System.out.println(osName);结果输出:Windows102.设置System.setProperty("jdbc.drivers"......