HackQuest Solidity 部分知识
uwupu 啦啦啦啦啦

这是一个不完整的笔记

参考文献:hackquest.io

abi函数编码

方法

abi.encodeWithSignature(SIGNATURE,...ARGS): 使用方法签名进行编码

abi.encodeWithSelector(SELECTOR,...ARGS): 使用selector进行编码。

EXAMPLE

使用 abi.encodeWithSignature 编码一个名为 transfer 的函数,传入的值为address类型的 msg.sender 和uint256类型的50

1
2
function transfer(address to, uint256 amount) {...}
abi.encodeWithSignature("transfer(address,uint256)", msg.sender, 50);

使用 abi.encodeWithSelector 函数编码一个名为 flashLoan 的函数,传入的参数为 address(this)100。(手动计算函数选择器

1
2
function flashLoan(address to, uint256 amount) {...}
abi.encodeWithSelector(bytes4(keccak256("flashLoan(address,uint256)")),address(this),100);

扩展

获取Selector

  1. 方法.selector。
  2. bytes4(keccak256("函数名(参数列表)"))可以通过字符串获取方法的selector(是否有些多此一举?)

低级调用 low level call

就是与EVM(以太坊虚拟机)进行交互。(类似于JVM的unsafe)

address.call 最基础的低级调用

address.call可以直接代表某地址执行合约的某个方法。

DOCS

(bool success, bytes memory data) = address(targetAddress).call{value: amount}(abiEncodedData);

  • targetAddress: 目标地址
  • value: amount: 发送以太币,可选参数
  • aboEncodeedData: 使用abi编码后的数据。

EXAMPLE

使用低级的 call 调用 targetAddress 地址的 dosome(uint256 amount) 函数,传参为5。(使用 abi.encodeWithSignature )

1
address(targetAddress).call(abi.encodeWithSignature("dosome(uint256)",5));

address.delegatecall

与call类似。这个会将要调用的函数复制到当前合约的上下文执行

==这个非常危险,经常发生安全漏洞和黑客攻击==

DOCS

1
(bool success, bytes memory data) = address(targetAddress).delegatecall(abiEncodedData);

场景

由于部署的 Solidity 合约不可更改,那我们希望更新函数功能的话怎么办呢?我们先部署一个代理合约 A,在里面 delegatecall 合约 B 的功能。

更新时,只需要更改合约 B 的地址变成合约 C,这样合约 A 就可以使用新版合约 C 的功能。

msg 全局变量

msg.value

获取调用者附加的以太币值

msg.data

bytes。包含了调用函数的原始数据

场景

当你调用合约的函数时,除了传递以太币外,还可以在函数调用中传递其他数据。这些数据可以是任何类型,包括字符串、字节数组等。通过使用 msg.data,您可以访问这些传递的数据,并在合约中执行相应的逻辑。

 评论