Минимальный прокси-контракт openzeppelin здесь имеет эту функцию предсказатьДетерминированныйАдрес(), которая хэширует такие значения, как адрес отправителя, соль... для генерации адреса контракта, который также будет генерировать функция create2, когда она передает те же значения, что и продиктованные в этом EIP.
В этом EIP указано, что произвольное значение 0xff при хэшировании с солью, адресом отправителя и байт-кодом контракта всегда будет генерировать один и тот же адрес.
Я пытаюсь реализовать функцию предсказатьДетерминированныйАдрес() в блокчейне TRON, но Документы ТРОН указывает другое произвольное значение, 0x41 для реализации этой же функции.
Я пытался просто заменить значения, но не вижу, где команда openzeppelin использовала значение 0xff в своей функции.
Ниже представлена хеш-функция openzeppelin:
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
Также из-за моих ограниченных знаний о ассемблере я не могу полностью понять, как именно работает их функция хеширования.
Может ли кто-нибудь объяснить мне или помочь мне понять, как эта функция может быть реализована в блокчейне TRON для получения желаемого эффекта?
По сути, я хочу иметь возможность передавать одни и те же значения в создать2, а также в эту функцию в блокчейне TRON и генерировать тот же адрес контракта.
Согласно официальной документации Solidity (https://docs.soliditylang.org/en/latest/control-structures.html?highlight=create2#salted-contract-creations-create2), алгоритм вычисления адресов create2 должен быть следующим:
keccak256(bytes1(0xff) ++ address(factory_contract)
++ bytes32(salt) ++ keccak256(bytes(creation_code) ++ bytes(arg...)))
Но на TRON алгоритм должен быть следующим:
keccak256(bytes1(0x41) ++ address(factory_contract)
++ bytes32(salt) ++ keccak256(bytes(creation_code) ++ bytes(arg...)))
Разница в том, что первый байт отдается внешней функции keccak256. EVM в Эфириуме — 0xff, TVM в TRON — 0x41.
Перед вычислением прогнозируемого адреса ( predicted := keccak256(add(ptr, 0x37), 0x55)
), начиная с (ptr), данные памяти:
0x00 ~ 0x13 3d602d80600a3d3981f3363d3d373d3d3d363d73
0x14 ~ 0x27 (implementation address)
0x28 ~ 0x37 5af43d82803e903d91602b57fd5bf3 ff (This byte is the key, should be replaced by 0x41 on TRON)
0x38 ~ 0x4b (deployer address)
0x4c ~ 0x6b (salt bytes32)
0x6c ~ 0x8b (keccak256(0x00 ~ 0x37)) (This part hash is keccak256(bytes(creation_code) ++ bytes(arg...)))
Это означает, что код создания прокси-контракта будет
0x3d602d80600a3d3981f3363d3d373d3d3d363d73(impl)5af43d82803e903d91602b57fd5bf3
.
Мы можем декомпилировать этот код на (https://ethervm.io/декомпилировать), результаты следующие:
(implementation address is replaced by 0xea674fdde714fd979de3edf0f56aa9716b898ec8)
label_0000:
// Inputs[3]
// {
// @0000 returndata.length
// @0006 returndata.length
// @0009 memory[returndata.length:returndata.length + 0x2d]
// }
0000 3D RETURNDATASIZE
0001 60 PUSH1 0x2d
0003 80 DUP1
0004 60 PUSH1 0x0a
0006 3D RETURNDATASIZE
0007 39 CODECOPY
0008 81 DUP2
0009 F3 *RETURN
// Stack delta = +1
// Outputs[3]
// {
// @0000 stack[0] = returndata.length
// @0007 memory[returndata.length:returndata.length + 0x2d] = code[0x0a:0x37]
// @0009 return memory[returndata.length:returndata.length + 0x2d];
// }
// Block terminates
000A 36 CALLDATASIZE
000B 3D RETURNDATASIZE
000C 3D RETURNDATASIZE
000D 37 CALLDATACOPY
000E 3D RETURNDATASIZE
000F 3D RETURNDATASIZE
0010 3D RETURNDATASIZE
0011 36 CALLDATASIZE
0012 3D RETURNDATASIZE
0013 73 PUSH20 0xea674fdde714fd979de3edf0f56aa9716b898ec8
0028 5A GAS
0029 F4 DELEGATECALL
002A 3D RETURNDATASIZE
002B 82 DUP3
002C 80 DUP1
002D 3E RETURNDATACOPY
002E 90 SWAP1
002F 3D RETURNDATASIZE
0030 91 SWAP2
0031 60 PUSH1 0x2b
0033 57 *JUMPI
0034 FD *REVERT
0035 5B JUMPDEST
0036 F3 *RETURN
Функция хеширования openzeppelin должна быть настроена на TRON следующим образом:
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf34100000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
Я предлагаю вам пойти на github или в дискорд TRON и создать проблему. ^ _ ^
Я не думаю, что в этом есть необходимость, вы уже решили мою проблему. Спасибо. Я имел в виду, как я могу узнать об обработке байтов и написании ассемблера.
Получите дополнительную информацию на (ethervm.io) и (docs.soliditylang.org/en/latest/assembly.html)
Здравствуйте, это работает. Большое спасибо, правда. Я пытался связаться с вами, но не смог найти контактную информацию или что-то в этом роде. Пожалуйста, пришлите мне DM, если вы не возражаете. Также, если вы можете предложить мне способ узнать об этом, я был бы очень признателен. Спасибо еще раз.