首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >web3.js是如何计算给它的参数的类型的?

问web3.js是如何计算给它的参数的类型的?
EN

Ethereum用户
提问于 2017-04-21 04:42:08
回答 1查看 1.4K关注 0票数 9

假设我有一个函数名重载的契约,可以采用不同的类型:

代码语言:javascript
复制
contract MyContract {
    event LogString(string str);
    event LogAddress(address addr);

    function logData(string str) {
        LogString(str);
    }
    function logData(address addr) {
        LogAddress(addr);
    }
}

这两个函数将有不同的函数签名,这取决于我传入的数据。但是,(我想)我通常会从JavaScript传入一个地址,如下所示:

mycontract.logData("0xdeadbeef")

web3.js是如何决定参数"0xdeadbeef"是address还是string的?如果这实际上包含了对粗心大意者的陷阱,那么命名这些函数的最佳实践是什么?我是否应该删除重载,并根据函数的预期数据类型给函数不同的名称?

EN

回答 1

Ethereum用户

回答已采纳

发布于 2017-04-25 13:12:02

前几天,我一直在想这种确切的行为,但没有时间调查。简单的回答是Javascript本身不允许函数重载,因此当契约对象从ABI构建时,相同名称的函数会被覆盖。

..。

以下是“同型印”(?)契约包含三个重载的函数,它们同名,相同的JS参数类型typeof "0x123" == "string",但具有不同的ABI参数类型,string,bytes,address

代码语言:javascript
复制
contract homosignet {
    function f(string s) constant returns (string){ return "was string";}
    function f(bytes b) constant returns (string){ return "was bytes";}
    function f(address a) constant returns (string){return "was address";}
}

我们在Remix中可以看到,这三种功能都是唯一的ABI函数,具有以下独特的功能特征:

代码语言:javascript
复制
fc68521a f(address)
d45754f8 f(bytes)
91e145ef f(string)

这三个函数都返回预期的字符串"was“、"was字节”和"was“。

但是,如果我使用web3.js钩住契约并从控制台调用结果JS对象的函数,如下面的测试代码和情况所示:

代码语言:javascript
复制
<html> <head><script src="web3.js"></script>
<script>
    web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));

var homosignetContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"s","type":"string"}],"name":"f","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"b","type":"bytes"}],"name":"f","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"}]);
k = homosignetContract.at("0x3b3d3de7a3271f0f6bea0b6b99e6f26a64dd3617");

</script></head></html>


> k.f(123)
"was string"
> k.f(0x123)
"was string"
> k.f("0x123")
"was string"
> k.f("test")
"was string"

返回值都是相同的,在本例中,所有参数都被解析为string类型,甚至是数字文本。

这是有意义的,因为Javascript不允许函数重载,而且当您查看契约对象时,实际上只有一个k.f()存在。

因此,调用重载函数似乎需要具有预编码调用对象的低级调用:

代码语言:javascript
复制
web3.eth.call(callObject [, defaultBlock] [, callback])

它在调用f(bytes b)时看起来是这样的。然后,您需要解码原始返回数据。

代码语言:javascript
复制
web3.eth.call({to:"0x7db0be9069df82feac77f810b26a6d8011b89a8c", data:"d45754f80000000000000000000000000000000000000000000000000000000000000123"})
票数 11
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/15385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档