繁体   English   中英

如何将以太币和数据从智能合约发送到 EOA?

[英]How do I send ether and data from a smart contract to an EOA?

我正在尝试创建从智能合约内部到 EOA 的“真实”交易。 这样我就可以附加 data/input_data 发送给它。

我已经阅读了一些关于此的资源,但我得到了相互矛盾的信息:有人说这是不可能的,有人说 call() 可以实现这一点。 我一直在测试多种方法,但还没有看到这是可能的。

这是我想要实现的一个简单示例:

pragma solidity 0.8.6;

contract Simple {
    uint32 value;
    constructor() payable {
        // Contract is initialized with 0.5 ether
        value = 22;
    }

    function foo() public {
        require(address(this).balance >= 0.1 ether);
        // Along with transfering ether, I want to send some data to the EOA,
        // for example, whichever value is in the variable "value"
        payable(msg.sender).transfer(0.1 ether);
    }
}

在“正常”交易中,可以设置“输入数据”字段(通常用于在将交易发送到智能合约时进行函数调用),这允许我们将交易数据从一个 EOA 发送到另一个 EOA . 我已经能够做到这一点。

但是,据我所知,合约“不能”创建交易; 他们只创建与“父交易”(首先调用合约的交易)相关联的“内部交易”(非正式名称),因此没有数据字段。 但是他们能够在网络上调用另一个合约,所以我假设他们能够沿着网络发送一些数据,对吧?

此外,这个问题似乎暗示低级 call() 方法能够实现这一点。 我尝试了多种方法,但无法重现想要的行为。

msg.sender.call{value: 0.1 ether}("data", value); // Doesn't work
msg.sender.call{value: 0.1 ether}(value); // Doesn't work
msg.sender.call{value: 0.1 ether}(abi.encodeWithSignature(value)) // Doesn't work

在某些时候,我确实在一个区块的“额外数据”上找到了我的消息,但根据我的理解,这是矿工出于某种原因写在那里的。

那么,总而言之,是否可以从合约中将以太+消息发送到 EOA 帐户? 我将如何实现这一目标?

编辑:修复了函数名称,这是一个保留关键字。

function msg() public {

这个函数名有点问题,因为你覆盖了全局msg变量,不能使用msg.sender

所以我将函数名称更改为通用foo()

function foo() public {

msg.sender.call{value: 0.1 ether}

从 Solidity 0.8 开始,默认情况下不payable address (来源: docs )。 因此,如果您想向他们发送本地货币(在以太坊的情况下,那就是 ETH),您需要先将addresspayable

payable(msg.sender).call{value: 0.1 ether}

最后到数据发送部分。

在某些时候,我确实在一个区块的“额外数据”上找到了我的消息,但根据我的理解,这是矿工出于某种原因写在那里的。

我不太确定,但您似乎偶然发现了正确的字段,它只是原始交易的data字段,区块链浏览器可能将其命名为“额外数据”。 data字段不是由矿工填写,而是由交易创建者填写。

由于您正在发送一个整数,并且data字段是bytesbytes数组),因此您需要将其编码为字节。 在你的情况下:

abi.encode(value)

你把它放在一起:

pragma solidity 0.8.6;

contract Simple {
    uint value;
    constructor() payable {
        value = 22;
    }

    function foo() public {
        require(address(this).balance >= 0.1 ether);
        payable(msg.sender).call{value: 0.1 ether}(abi.encode(value));
    }
}

当你执行foo()函数(并且合约有足够的资金)时,它会创建一个内部交易(一些区块链浏览器可能使用不同的名称)到msg.sender ,值为0.1 ether十进制22编码为十六进制16data字段中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM