简介

区块链上的所有操作都是通过交易(Transaction)上链的,无论你是转账交易还是发起的智能合约的调用,而EOS和传统区块链不同的是EOS在一个交易里可以发起多个行为(Action),这使得EOS的操作可以支持更原子化的事务控制,也同时为上链增加了便捷性和可操作性。而今天我们就要学习下EOS中的交易的结构和交易的操作。

交易结构

我们先用之前账号管理篇章中使用的创建系统账号的方法来看一下一个交易的结构。

cleos create account eosio astaldo \
EOS6nbWS7ZReiPMdMABoEmVBYanyTMb3GYRQGsTRMCYx9vijWoaS3 \
EOS6nbWS7ZReiPMdMABoEmVBYanyTMb3GYRQGsTRMCYx9vijWoaS3 \
-j -d

  

和之前不同的是我们在最后加上了两个参数,-j表示输出json格式数据,-d表示不进行交易广播。因为没有广播,所以交易并不会上链。

{
"expiration": "2020-04-29T08:27:24",
"ref_block_num": 79,
"ref_block_prefix": 199531063,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio",
"name": "newaccount",
"authorization": [{
"actor": "eosio",
"permission": "active"
}
],
"data": "0000000000ea305500000080a668323601000000010002fa026835dadff4e20d401c1d912a819dfcb3b08372a0feda23ad257e9c65b7580100000001000000010002fa026835dadff4e20d401c1d912a819dfcb3b08372a0feda23ad257e9c65b75801000000"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_K72sFmvGoPCYB9es4cfceuyzSj6fJqtVpnikG7v9vXssQHnRJHGnNSRcu1S4oV5prmASEfYyWRP9rst9HKjV7nNttysL3o"
],
"context_free_data": []
}

  

我们来看下一个交易的基本结构。首先可以看到actions字段是一个数组集合,这就是为了支持同一交易中进行多个action操作,这个我下面会单独再说。我们来说说主要的字段:

expiration 该交易上链的有效期,过期未能上链便会返回交易过期的异常。
ref_block_num 引用区块号
ref_block_prefix 引用区块的前缀
delay_sec 延时执行时间(s)
actions 交易包含的行为集合
signatures 交易的签名集合

我们再来看action的基本结构:

account 账号名,即合约账号名
name 行为名称,也可以理解为智能合约的方法名
authorization 授权集合,调用这个action所要用到的账号权限
data 行为参数数据的打包数据

接下来我给大家看一个相对复杂的交易。

cleos -u "http://jungle2.cryptolions.io" \
system newaccount --stake-net '1 EOS' --stake-cpu '10 EOS' \
--buy-ram-kbytes 1000 eosastaldo11 eosastaldo33 \
EOS8h8YD7956jYf99BV6kBit5d9461xaxyTf9HPxmARcnTEnFivY8 \
EOS7DhW1StAhprCBwpAfgMpmHuN2H3V8t4B45tzQtEYckHRr5CASN \
-p eosastaldo11@active -p eosastaldo22@active \
-j -d

  

这里使用创建普通账号的方法,这里调用的是jungle测试网,并使用了两个账号来签名(这里只是为了构建一个复杂的交易,但是使用多账号签名其实也是有实际意义的,可以借用资源,这个我们稍后补充说明)

  "expiration": "2020-04-29T09:38:15",
"ref_block_num": 50179,
"ref_block_prefix": 686944513,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio",
"name": "newaccount",
"authorization": [{
"actor": "eosastaldo11",
"permission": "active"
},{
"actor": "eosastaldo22",
"permission": "active"
}
],
"data": "10024dd1646c305530064dd1646c305501000000010003f4fe1f6168380331582f3c4dca57b5f9ce4098b999b44e0a9945ff216c2d55690100000001000000010003330272e86792b3b335277c64d9ea1e1988a192f734774df22012ac562b19b7d001000000"
},{
"account": "eosio",
"name": "buyrambytes",
"authorization": [{
"actor": "eosastaldo11",
"permission": "active"
},{
"actor": "eosastaldo22",
"permission": "active"
}
],
"data": "10024dd1646c305530064dd1646c305500a00f00"
},{
"account": "eosio",
"name": "delegatebw",
"authorization": [{
"actor": "eosastaldo11",
"permission": "active"
},{
"actor": "eosastaldo22",
"permission": "active"
}
],
"data": "10024dd1646c305530064dd1646c3055102700000000000004454f5300000000a08601000000000004454f530000000000"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_Kk9kasEiNqQyEvkwSUFidAgzZVcPJGifSULX48F7qiCmmnz3ucrg6fb9V5YCEkK73oGP44j26MeT96UxLPBo1auCLbqFEM",
"SIG_K1_KhKTiKFK96hTnHRAzW69TTjFnrAh4FTCgHbfASoAFzauYwfNJ1jYmW4sa6AX57ihG94FbA1TKJZEYSUgNbzsJUq35dXJSf"
],
"context_free_data": []
}

  

我们注意到有三个主要的不同,一个是actions里面有3个action,分别是newaccount、buyram和delegatebw,对应的是创建账号、购买内存和抵押资源。而每个action中的authorization也都有两个,正是我们指定签名的eosastaldo11@active和eosastaldo22@active。最后一个是signatures里面也有两个签名,对应了我们使用的两个账号权限的签名。

补充:上面提到了使用两个账号签名,这个功能其实可以有两个实际作用:

1 - EOS中在1.8以后支持了借用资源的功能,说白了就是当有多个action或者action中有多个authorization时,只扣减第一个账号的CPU和NET资源。而这个功能在CPU价格疯涨的现在,被普遍应用于为某些资源低的账号提供CPU和NET使用。
2 - 合约中可以进行多个账号的权限验证,只有用户同时拥有多个账号私钥时才可进行的操作。和多签功能不同的是,这个签名方式将可以在一个交易中完成对多个权限的验证,而多签主要应用在多个不同所属账号间的授权,且只能进行单账号权限的验证。

发起交易的流程

我们通过命令行获得的交易数据,其实是经过了很多步骤才获得的,我这里只简单说明下,细节和实现我们会在后面的深度剖析版块慢慢说明。

action打包数据

首先需要把所有action进行打包,怎么打包呢?获取这个action的合约账号的abi信息,然后将这个action的参数进行类型序列化,最后生成wasm格式的数据。也就是我们上面将交易结构中看到的类似于10024dd1646c305530064dd1646c305501000000010003f4fe1f6168380331582f3c4dca57b5f9ce4098b999b44e0a9945ff216c2d55690100000001000000010003330272e86792b3b335277c64d9ea1e1988a192f734774df22012ac562b19b7d001000000这样的数据。

获取区块信息

我们既然要上链,就要和区块关联起来,所以我们需要获取现在最新的区块号,并获得该区块号的前缀信息。这些都可以通过RPC接口获得,然后我们的交易上链需要设置一个过期时间(广播出去后要等到上链是有一定的时间差的,我们通过过期时间来控制交易的有效性)。

如果你这个交易还是一个延时交易(大部分交易都是即时发生并上链的,有时我们需要延时调用,比如在某个特定的时间执行的操作),那你还需要设置延时时间。

签名

交易要进行签名前,我们需要把交易打包生成wasm数据,并按照特定格式组装后再用私钥签名。

需要用哪些私钥进行签名呢,我们会将action中的authorization都取出来,通过RPC接口查询可以用于签名的公钥有哪些,然后我们和自己拥有的密钥对进行比对,就可以获得签名要使用的私钥了。

为了将交易数据和链关联,预签名数据里会用到chainid。将签名放入signatures字段。至此,我们的交易就准备好了。

广播

交易组装完后就要发到节点上,节点进行校验和执行后,会广播出去,由超级节点打包到区块中,再将区块广播出去,经过共识机制验证后最终达到不可逆,完成上链。

发起转账交易

我们现在来通过cleos tranfer命令进行一个转账。命令有几个核心参数。

-c,—contract TEXT Token合约的账号名,默认eosio.token
sender 发起转账的账号,同action中的from
recipient 接收转账的账号,同action中的to
amount 账号金额,”0.0000 EOS”格式,同action中的quantity
memo 备注,同action中memo

我们使用EOS testnet的环境,从我的账号xxsizdfracfg转10个TNT给ywndohtegtui。

cleos -u https://api.testnet.eos.io transfer xxsizdfracfg ywndohtegtui "10.0000 TNT" "for test, fishopark.com"

  

如果你要转的并不是系统代币(EOS主网的代币就是EOS),那你还需要指定-c参数,说明代币的合约账号。比如,我在EOS测试网上发行了一个TADO的代币,现在我要从ywndohtegtui转给xxsizdfracfg。

cleos -u https://api.testnet.eos.io transfer -c ywndohtegtui ywndohtegtui xxsizdfracfg "1.0000 TADO" "for test, fishopark.com"

  

调用合约Action

我们知道转账其实也是一个action操作,cleos封装了这个常用操作,而创建新账号也是,cleos将这个有3个action的操作封装了。那么我们自己进行合约调用操作该怎么进行呢?

简单合约Action调用调用直接通过cleos push action命令调用,而复杂交易或者多Action调用的交易则需要通过cleos push action -d -j先获取各Action数据,然后手动拼装transaction后,通过cleos push transaction发起。

这里我们只介绍单Action的调用,多Action的调用会在后续介绍多签等内容是消息介绍。cleos push action命令有几个核心参数。

account 合约账号名
action action名称
data 参数,支持字符串数组和json格式。

我们调用一个Action需要先了解这个Action所在的合约名,Action的名字,已经参数的名称和类型,而这些大多都可以通过合约的Abi信息中获得。

假设我现在还是要调用EOS测试网上我发行的token合约的ywndohtegtui账号上的issue,那么:

account: ywndohtegtui
action: issue
data:

to: ywndohtegtui
quantity: 99.0000 TADO
memo: push action test, fishopark.com

因为官方标准Token合约中限制了发行只能发行给发行人,所以这里我们发行给ywndohtegtui。

#使用字符串数组格式
cleos -u https://api.testnet.eos.io push action ywndohtegtui issue '["ywndohtegtui","99.0000 TADO","push action test, fishopark.com"]' -p ywndohtegtui@active #或者使用json数据格式
cleos -u https://api.testnet.eos.io push action ywndohtegtui issue '{"to":"ywndohtegtui","quantity":"99.0000 TADO","memo":"push action test, fishopark.com"}' -p ywndohtegtui@active

  

 

EOS基础全家桶(十)交易Action操作的更多相关文章

  1. EOS基础全家桶(十四)智能合约进阶

    简介 通过上一期的学习,大家应该能写一些简单的功能了,但是在实际生产中的功能需求往往要复杂很多,今天我就继续和大家分享下智能合约中的一些高级用法和功能. 使用docker编译 如果你需要使用不同版本的 ...

  2. EOS基础全家桶(七)合约表操作

    简介 本篇我们开始来为后续合约开发做准备了,先来说说EOS内置的系统合约的功能吧,本篇将侧重于合约表数据的查询,这将有利于我们理解EOS的功能,并可以进行必要的数据查询. EOS基础全家桶(七)合约表 ...

  3. EOS基础全家桶(十二)智能合约IDE-VSCode

    简介 上一篇我们介绍了EOS的专用IDE工具EOS Studio,该工具的优势是简单,易上手,但是灵活性低,且对系统资源开销大,依赖多,容易出现功能异常.那么我们开发人员最容易使用的,可能还是深度定制 ...

  4. EOS基础全家桶(八)jungle测试网的使用

    简介 前面我们已经学习了一些EOS的基础知识了,但是在EOS主网上的很多操作(比如:抵押.赎回.买卖内存)都是需要EOS链被正式激活后才可使用,而激活EOS链还需要很多的准备操作,我打算在单独的一篇文 ...

  5. EOS基础全家桶(五)钱包管理

    简介 本篇我们将会学习EOS自带的命令行钱包的使用方法,我们将会使用cleos来控制keosd服务对本地钱包进行管理. 虽然现在市面上已经有很多支持EOS的钱包了,有Web钱包,有app钱包,还有浏览 ...

  6. EOS基础全家桶(六)账号管理

    简介 本篇我们会学习最基本的账号相关的操作,包括了创建账号和查询,关于账号资源的操作因为必须先部署系统合约,所以我们会留到后面单独写一篇来讲解. 6-EOS基础全家桶(六)账号管理 简介 账号介绍 账 ...

  7. EOS基础全家桶(十五)智能合约进阶2

    简介 今天我们继续补充智能合约的进阶使用技巧,这次的主题是交易,合约内我们除了可以发起内联action的调用,很多使用还需要直接调用其他的合约action或者以交易的形式调用自身的action. 发起 ...

  8. EOS基础全家桶(十三)智能合约基础

    简介 智能合约是现在区块链的一大特色,而不同的链使用的智能合约的虚拟机各不相同,编码语言也有很大差异.而今天我们开始学习EOS的智能合约,我也是从EOS初期一直开发合约至今,期间踩过无数坑,也在Sta ...

  9. EOS基础全家桶(十一)智能合约IDE-EOS_Studio

    简介 我们马上要进入智能合约的开发了,以太坊最初提供了智能合约的功能,并宣告区块链进入2.0时代,而EOS的智能合约更进一步,提供了更多的便利性和可能性.为了进一步了解智能合约,并进行开发,我们需要先 ...

随机推荐

  1. python3(二十三)classInstance

    """ 类和实例和访问权限 """ __author__ = 'shaozhiqi' # class后面紧接着是类名,即Student,类名 ...

  2. Spring温习(1)--最基础的示例

    Spring温习(1)--最基础的示例 博客分类: 框架-Spring专栏 SpringXMLBeanWebDAO 从现在开始,我将从Spring为起点,逐步复习几大框架各方面的知识,以便今后查看使用 ...

  3. 数据结构和算法(Golang实现)(19)排序算法-冒泡排序

    冒泡排序 冒泡排序是大多数人学的第一种排序算法,在面试中,也是问的最多的一种,有时候还要求手写排序代码,因为比较简单. 冒泡排序属于交换类的排序算法. 一.算法介绍 现在有一堆乱序的数,比如:5 9 ...

  4. CVE-2019-0193 远程命令执行-漏洞复现

    0x01 漏洞简介 Apache Solr 是一个开源的搜索服务器.Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现.此次漏洞出现在Apache Solr的 ...

  5. Java 基础增强

    jdk与jre 要想深入了解Java必须对JDK的组成, 本文对JDK6里的目录做了基本的介绍,主要还是讲解 了下JDK里的各种可执行程序或工具的用途 Java(TM) 有两个平台 JRE 运行平台, ...

  6. 【jmeter】JDBC请求循环调用的问题

    今天使用jdbc请求从数据库取数据,多次请求使用了循环控制器,但是结果第一个jdbc请求返回值正确,第二次请求返回值为空. 1.从其他博客中得知,需要在jdbc connection configur ...

  7. vue2.x学习笔记(九)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12577948.html. 数组的更新检测 数组在javascript是一种特殊的对象,不是像普通的对象那样通过Ob ...

  8. Shellshock远程命令注入(CVE-2014-6271)漏洞复现

    请勿用于非法用法,本帖仅为学习记录 shelshocke简介: shellshock即unix 系统下的bash shell的一个漏洞,Bash 4.3以及之前的版本在处理某些构造的环境变量时存在安全 ...

  9. 它来了!它来了!Seata Go Client 它来了!!!

    抱歉抱歉,这个标题一看就是个很标题党的标题.本文所述的 Seata Go Client 只支持 TCC 模式,并不像 Java 版的能支持到 AT 模式.SAGA 模式.XA 模式,聊胜于无.说到这里 ...

  10. 2019-2020-1 20199303 《Linux内核原理与分析》 第十一周作业

    缓冲区溢出漏洞实验 安装一些用于编译C程序的32位软件包 sudo apt-get install -y lib32z1 libc6-dev-i386 sudo apt-get install -y ...