Eth Transfer

ETH交易一般理解都是转账交易,但是这个理解是比较狭隘的。这里谈到的交易是一种广义的交易。

交易的发起者:主要是两类
  1. 节点服务,geth控制太。
  2. 调用节点服务,主要是指geth提供RPC接口的客户端,如wallet等。
交易分类:主要是两类
  1. ETH转账交易
  2. 其他交易,包含不限于ERC20 Token的转账交易。
交易相关的RPC接口:eth_sendTransaction And eth_sendRawTransaction

这两个函数以需不需调用者手动进行对最终的参数签名作为区分

  1. eth_sendTransaction:该函数仅用于ETH转账,参数最终的签名不需要调用者手动进行,它会在当前节点中使用已解锁的发起者from的ETH的地址私钥进行签名,因此需要在每次调用该函数进行ETH转账时,需要先解锁from地址。
  2. eth_sendRawTransaction:需要调用者使用from的私钥进行签名参数数据的交易函数,目前的 ERC20 Token转账交易都使用这个函数。ETH转账一样可以使用该函数进行转账,但转账ETH主要由参数来控制。
交易和智能合约的关系

一开始就说到交易有一种狭隘的理解,就是指智能合约的交易(transfer).
那么,广义的交易和狭隘的交易的关系是怎样的?
首先,转账交易首先是调用eth_sendRawTransaction这个RPC接口,把转账交易需要的参数传给节点,节点拿到数据后,提取每个数据字段,其中就包含eth_sendRawTransaction的data参数,data是一个十六进制字符串,它所组成的内容中,就包含methodId,该Id对应的就是transfer函数的名称化后的值。
接着,再根据to参数找到该智能合约,然后基于data的methodId来找到所指是的函数,最后根据data的参数如转给谁,转多少,执行该函数。
执行函数后,无论执行成功失败,都会返回一个交易哈希值(全称是"Transaction Hash", 简称txHash)
在这里插入图片描述

交易参数的说明

1.from
代表的是从哪个地址发起交易,如果交易的to是只能合约地址,那么合约代码中的msg.sender变量代表的就是这个地址from地址。
2.to
代表当前交易的接收地址。注意的是,接收地址不能理解为收款地址,以为to的取值有3种情况:

  1. 智能合约的地址
    当前所发送的交易将会交给对应的智能合约处理,原理和ERC20转账相同。所以在进行ERC20代币转账时,to应该是智能合约的地址。
  2. 普通ETH用户的钱包地址
    就是普通的ETH转账,to就是收款地址。
  3. 取值为空,代签当前的交易是创建智能合约的交易
    代表当前的交易是部署智能合约到链上的交易。

3.value:转账数值
(1)在使用的eth_sendRawTransaction进行ERC20 Token转账时,value应该是0.
(2)在进行ERC20 Token转账时,所要转账的值的多少定义在data的参数.
(3)在使用eth_sendRawTransaction进行转账时,value必须有值,并且这个值是 1 0 18 10^{18} 1018的形式的大数值,如 2 代表 2 ∗ 1 0 18 2*10^{18} 21018.
当使用eth_sendRawTransaction进行ETH转账交易的时,有3点需要注意:

  1. to应该是收款钱包的地址
  2. value对应的是ETH数值,不是0.
  3. data参数为空字符串.

4.gas
这个gas就是gasLimit,但是交易成功时所使用的是GasUser。交易成功时多出的燃料费会返回,返回的部分就是(gasLimit - GasUser)*gasPrice.

5.gasPrice
这个就是单价,单位wei,这是个动态值。

6.nonce
交易序列号,防止双花就是靠这个。

7.data
这是一个比较重要的参数,不仅用在交易接口,也用在eth_call中。
data格式必须满足的要求:

  1. 十六进制格式
0xa9059cbb0000000000000000000000007198ef99ac39c713ea1e333db4dc46c8b4413bf100000000000000000000000000000000000000000000000000000002cb417800
  1. 如上面,前面10个字符,包含0x,是methodId,它的生成方式比较复杂,是由合约函数的名称经过签名后,通过Keccak256加密去特定数量的字节,然后转为16进制得出。下面是ETH版本标准生成methodId的代码:
func (method Method) Id() []bety{
	return crypto.Keccak256([]byte(mothod.Sig()))[:4]
}

常见的函数对应的methodId,有下面两种:

  • 查询余额:balanceOf是0x70a08231
  • 转账:transfer是 0xa9059cbb
  1. 前10个之后的字符,满足下面的条件
  • 代表的是智能合约中函数的参数
  • 排序方式按照合约参数的顺序排列
  • 十六进制的形式
  • 不允许有0x,即先转成16进制形式再去掉0x字符
  • 去掉0x后,每个参数字符个数是64
举个栗子:
onMethod(arg1,arg2,....)
data的格式应该是
methodId + hex64(arg1) + hex64(arg2) + hex64(arg3) + ....
eth_sendTransaction({from:"0x...", to:"0x...",value=某数值)
最少三个参数

sendTransaction已经被ETH封装好了,它只能被用来转账ETH,本质上和sendRawTranscation是一样的,被封装好的sendTransaction,此时的data被设置成了发起交易的附属信息,类似于备注。

交易的状态(生命周期)

一共四种状态

  1. Unkonw(未知状态):还没放进txPool ETH 交易池中,这个时候根据txHash使用区块浏览器查询,是没有任何信息的。
  2. Pending(等待或者挂起状态):此时根据txHash使用区块浏览器查询,是可以查询部分交易信息的
  3. Success(成功状态):交易成功,可以根据txHash使用区块浏览器查询到交易的任何信息
  4. Failed(失败状态):交易失败,根据txHash使用区块浏览器查询查到失败信息及其失败原因

因为受ETH Pool大小的影响,会造成一些订单只是被处于被放置到交易池,尚未被交易的状态,该状态激就是Unkwon(位置状态)。
造成这种原因,是因为minter在交易池中的交易订单的排序算法受GasPrice的影响,GasPrice高的订单会挤掉GasPrice低的订单,有可能会导致一个订单,一直处于Pending中,可能搁置几天甚至更久。(这种情况遇到过)

在这里插入图片描述

交易的打包

在这里插入图片描述
TIP:在minter打包交易时,“再次校验交易”的步骤,内部拥有一次交易燃料费的计算步骤,EVM计算gas的流程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Python的Eth代币转账实现代码示例,需要使用web3.py库: ```python from web3 import Web3 import json # 1. 连接到以太坊节点 web3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/{your-infura-project-id}')) # 2. 加载代币合约ABI with open('abi.json', 'r') as abi_definition: abi = json.load(abi_definition) # 3. 获取代币合约 contract_address = '0x1234567890123456789012345678901234567890' contract = web3.eth.contract(address=contract_address, abi=abi) # 4. 发送代币转账交易 token_sender_address = '0x1234567890123456789012345678901234567890' token_sender_private_key = '{your-private-key}' token_receiver_address = '0x0987654321098765432109876543210987654321' token_amount = 1000 gas_limit = 100000 gas_price = web3.toWei('20', 'gwei') # 获取nonce值 nonce = web3.eth.getTransactionCount(token_sender_address) # 构造交易数据 transaction = { 'nonce': nonce, 'to': contract_address, 'value': 0, 'gas': gas_limit, 'gasPrice': gas_price, 'data': contract.functions.transfer(token_receiver_address, token_amount).buildTransaction({'from': token_sender_address}).hex(), } # 对交易进行签名 signed_txn = web3.eth.account.signTransaction(transaction, private_key=token_sender_private_key) # 发送交易 tx_hash = web3.eth.sendRawTransaction(signed_txn.rawTransaction) # 等待交易被打包 tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash) # 打印交易信息 print(f'Transaction sent: {tx_hash.hex()}') print(f'Transaction receipt: {tx_receipt}') ``` 其中,需要将代码中的以下参数替换为实际的值: - `{your-infura-project-id}`:Infura项目ID - `abi.json`:代币合约ABI文件路径 - `contract_address`:代币合约地址 - `token_sender_address`:代币发送者地址 - `token_sender_private_key`:代币发送者私钥 - `token_receiver_address`:代币接收者地址 - `token_amount`:代币数量 - `gas_limit`:交易的gas限制 - `gas_price`:交易的gas价格 需要注意的是,这只是一个简单的示例代码,实际使用中需要根据具体情况进行调整和完善。同时,在使用时需要非常小心,以免出现错误导致代币丢失。建议在测试环境中进行充分的测试,确保代码的正确性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值