baseDAO
合约中的
propose
入口点可用于动态添加新的提案处理程序(作为已接受提案的结果执行的逻辑)。我的目标是添加一个处理程序,支持任意合约交互,允许合约调用任何已部署合约上的任何端点。通话数据的验证是通过这个 Ligo 逻辑完成的,它具有以下结构:
(pair %add_handler
(pair (lambda %code
(pair (pair (map %handler_storage string bytes) (bytes %packed_argument))
(pair %proposal_info
(address %from)
(nat %frozen_token)
(bytes %proposal_metadata)))
(pair (pair (option %guardian address) (map %handler_storage string bytes))
(list %operations operation)))
(lambda %handler_check (pair bytes (map string bytes)) unit))
(string %name))
这是一个通过验证的基本示例:
(Left (Left (Pair (Pair {
DROP ;
NIL operation ;
EMPTY_MAP string bytes ;
NONE address ;
PAIR ;
PAIR }
{ DROP ; UNIT })
"sample")))
在上面的结构中,我想集成转发合约调用的逻辑:
parameter (pair (address :destination) (pair (string :entrypoint) (bytes :parameter)));
storage unit;
code {
CAR;
UNPAIR;
# Extract the destination contract address
UNPAIR;
# Convert the string to an entrypoint address
CONTRACT (unit);
IF_NONE { FAILWITH } { };
# Pack the parameter bytes
PUSH mutez 0; # No tez is sent
UNPAIR;
PACK;
# Call the target contract with the provided entrypoint and parameter
TRANSFER_TOKENS;
NIL operation;
CONS;
PAIR;
};
这就是我试图将它们组合在一起的方式:
(Left (Left (Pair
(Pair {
UNPAIR ; SWAP ; UNPAIR ; SWAP ; DROP ; UNPAIR ;
CAR; UNPAIR; UNPAIR;
CONTRACT (unit %entrypoint);
IF_NONE { FAILWITH } {};
PUSH mutez 0; UNPAIR; PACK;
TRANSFER_TOKENS;
NIL operation; CONS;
SWAP; PAIR;
NONE address; PAIR
}
{ DROP; UNIT }
) "arbitrary_contract_interaction")))
它被合约验证者拒绝:A FAILWITH instruction was reached {"int":"111"}
here(参见None
案例失败,并显示
unpacking_proposal_metadata_failed
,相当于111,正如您在here所见)。 我建议您使用
octez-client
来验证您的迈克尔逊与
octez-client -M mockup convert script <contract.tz> from michelson to michelson
是否正确。如果您使用 Visual Studio 代码,您可以尝试使用此扩展
nomadiclabs.vscode-michelson
来获得一些颜色,它应该告诉您您的 Michelson 是否有效,但对于某些事情来说它可能已经过时,所以我认为您应该始终检查
octez-client
命令。例如,如果我接受你的合同:
parameter (pair (address :destination) (pair (string :entrypoint) (bytes :parameter)));
storage unit;
code {
CAR;
UNPAIR;
# Extract the destination contract address
UNPAIR;
# Convert the string to an entrypoint address
CONTRACT (unit);
IF_NONE { FAILWITH } { };
# Pack the parameter bytes
PUSH mutez 0; # No tez is sent
UNPAIR;
PACK;
# Call the target contract with the provided entrypoint and parameter
TRANSFER_TOKENS;
NIL operation;
CONS;
PAIR;
};
这里是octez-client
命令的返回:
Ill typed contract:
01: { parameter (pair (address :destination) (pair (string :entrypoint) (bytes :parameter))) ;
02: storage unit ;
03: code { CAR
04: /* [ pair address string bytes ] */ ;
05: UNPAIR
06: /* [ address : pair string bytes ] */ ;
07: UNPAIR ;
08: CONTRACT unit ;
09: IF_NONE { FAILWITH } {} ;
10: PUSH mutez 0 ;
11: UNPAIR ;
12: PACK ;
13: TRANSFER_TOKENS ;
14: NIL operation ;
15: CONS ;
16: PAIR } }
At line 7 characters 9 to 15, wrong stack type for instruction UNPAIR:
[ address : ... ].
为了帮助您实现您想要做的事情,这里有一个合约,它通过您提供的基本示例传递命令
{ parameter unit ;
storage unit ;
code { DROP ;
PUSH (or (or (pair (pair (lambda
(pair (pair (map %handler_storage string bytes) (bytes %packed_argument))
(pair %proposal_info
(address %from)
(nat %frozen_token)
(bytes %proposal_metadata)))
(pair (pair (option %guardian address) (map %handler_storage string bytes))
(list %operations operation)))
(lambda (pair bytes (map string bytes)) unit))
string)
unit)
unit)
(Left (Left (Pair (Pair { DROP ;
NIL operation ;
EMPTY_MAP string bytes ;
NONE address ;
PAIR ;
PAIR }
{ DROP ; UNIT })
"sample"))) ;
DROP ;
UNIT ;
NIL operation ;
PAIR } }
您只需将基本示例替换为您想要测试的示例,并且合约是否通过 octez-client
命令您的 Michelson 类型检查。为了帮助您编写 Michelson,您应该查看
文档,因为复杂的 Michelson 会变得非常难以阅读,并且很容易丢失堆栈的跟踪。
仅凭您的 Michelson,我不完全理解您希望如何实现此处理程序,因为调用合约时您必须尊重其签名。我希望它有帮助:)