在 Azure Function 上使用 web3.js 调用 Ethereum
Posted
技术标签:
【中文标题】在 Azure Function 上使用 web3.js 调用 Ethereum【英文标题】:Call Ethereum using web3.js on Azure Function 【发布时间】:2018-04-13 18:04:44 【问题描述】:我正在尝试使用 Azure Function 通过 Web3.js 调用 Ethereum,代码在命令 shell 中似乎运行良好,但是当我将它作为函数运行时出现错误。
在 Azure 门户上创建一个新的 javascript Azure 函数:
转到平台功能 --> 开发工具 --> 高级工具 (kudu) --> 调试控制台 --> CMD
cd 网站 cd wwwroot 光盘 npm install web3@^0.20.0
创建一个新的 code.js 文件
const Web3 = require('web3'); var web3 = new Web3(); const httpProv = new Web3.providers.HttpProvider("http://:8545"); web3.setProvider(httpProv); console.log(web3.eth.blockNumber);
在 CMD shell 中执行这个文件
节点代码.js
工作正常,我可以看到一个 HTTP Post 请求
请求:
POST / HTTP/1.1 用户代理:node-XMLHttpRequest 接受:/ 内容类型:应用程序/json 主持人: : 内容长度:63 连接:关闭
"jsonrpc":"2.0", "id":1,"method":"eth_blockNumber","params":[]
回复:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date:
Content-Length:
Connection:close
"jsonrpc":"2.0", "id":1,"result":"bla"
我在 wwwroot 目录中创建了一个 package.json 文件
"frameworks":
"net46":
"dependencies":
"web3": "^0.20.0"
然后跑了
npm install
当我执行 Azure 函数时,我得到了这个错误:
2017-10-30T08:31:44.291 Function started (Id=f28edf73-fa02-406d-868e-0f23cd41e6e0)
2017-10-30T08:31:44.338 Exception while executing function: Functions.AZURE_FUNCTION. mscorlib: Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.
at Object.InvalidConnection (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\errors.js:31:16)
at HttpProvider.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\httpprovider.js:84:18)
at RequestManager.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\requestmanager.js:58:32)
at Eth.get [as blockNumber] (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\property.js:107:62)
at module.exports (D:\home\site\wwwroot\AZURE_FUNCTION\index.js:8:25)
at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11296\bin\azurefunctions\functions.js:99:24.
2017-10-30T08:31:44.385 Function completed (Failure, Id=f28edf73-fa02-406d-868e-0f23cd41e6e0, Duration=94ms)
2017-10-30T08:31:44.385 Exception while executing function: Functions.AZURE_FUNCTION
2017-10-30T08:31:44.385 Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.
at Object.InvalidConnection (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\errors.js:31:16)
at HttpProvider.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\httpprovider.js:84:18)
at RequestManager.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\requestmanager.js:58:32)
at Eth.get [as blockNumber] (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\property.js:107:62)
at module.exports (D:\home\site\wwwroot\AZURE_FUNCTION\index.js:8:25)
at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11296\bin\azurefunctions\functions.js:99:24
2017-10-30T08:31:44.385 Function completed (Failure, Id=f28edf73-fa02-406d-868e-0f23cd41e6e0, Duration=94ms)
2017-10-30T08:31:44.385 Executed 'Functions.AZURE_FUNCTION' (Failed, Id=f28edf73-fa02-406d-868e-0f23cd41e6e0)
2017-10-30T08:31:44.385 Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.
at Object.InvalidConnection (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\errors.js:31:16)
at HttpProvider.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\httpprovider.js:84:18)
at RequestManager.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\requestmanager.js:58:32)
at Eth.get [as blockNumber] (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\property.js:107:62)
at module.exports (D:\home\site\wwwroot\AZURE_FUNCTION\index.js:8:25)
at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11296\bin\azurefunctions\functions.js:99:24
2017-10-30T08:31:44.385 Function had errors. See Azure WebJobs SDK dashboard for details. Instance ID is 'f28edf73-fa02-406d-868e-0f23cd41e6e0'
2017-10-30T08:31:44.385 Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.
at Object.InvalidConnection (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\errors.js:31:16)
at HttpProvider.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\httpprovider.js:84:18)
at RequestManager.send (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\requestmanager.js:58:32)
at Eth.get [as blockNumber] (D:\home\site\wwwroot\AZURE_FUNCTION\node_modules\web3\lib\web3\property.js:107:62)
at module.exports (D:\home\site\wwwroot\AZURE_FUNCTION\index.js:8:25)
at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11296\bin\azurefunctions\functions.js:99:24
2017-10-30T08:31:44.400 "id":"4e755d0e-a2cf-4c4a-a734-aa750555a948","requestId":"4fa42aca-ff49-487a-a543-8f82295a1e5c","statusCode":500,"errorCode":0,"message":"Exception while executing function: Functions.AZURE_FUNCTION -> Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.\n at Object.InvalidConnection (D:\\home\\site\\wwwroot\\AZURE_FUNCTION\\node_modules\\web3\\lib\\web3\\errors.js:31:16)\n at HttpProvider.send (D:\\home\\site\\wwwroot\\AZURE_FUNCTION\\node_modules\\web3\\lib\\web3\\httpprovider.js:84:18)\n at RequestManager.send (D:\\home\\site\\wwwroot\\AZURE_FUNCTION\\node_modules\\web3\\lib\\web3\\requestmanager.js:58:32)\n at Eth.get [as blockNumber] (D:\\home\\site\\wwwroot\\FUNCTION_NAME\\node_modules\\web3\\lib\\web3\\property.js:107:62)\n at module.exports (D:\\home\\site\\wwwroot\\FUNCTION_NAME\\index.js:8:25)\n at D:\\Program Files (x86)\\SiteExtensions\\Functions\\1.0.11296\\bin\\azurefunctions\\functions.js:99:24"
2017-10-30T08:31:44.400 Error: CONNECTION ERROR: Couldn't connect to node http://IP_ADDR:8545.
at Object.InvalidConnection (D:\home\site\wwwroot\FUNCTION_NAME\node_modules\web3\lib\web3\errors.js:31:16)
at HttpProvider.send (D:\home\site\wwwroot\FUNCTION_NAME\node_modules\web3\lib\web3\httpprovider.js:84:18)
at RequestManager.send (D:\home\site\wwwroot\FUNCTION_NAME\node_modules\web3\lib\web3\requestmanager.js:58:32)
at Eth.get [as blockNumber] (D:\home\site\wwwroot\FUNCTION_NAME\node_modules\web3\lib\web3\property.js:107:62)
at module.exports (D:\home\site\wwwroot\FUNCTION_NAME\index.js:8:25)
at D:\Program Files (x86)\SiteExtensions\Functions\1.0.11296\bin\azurefunctions\functions.js:99:24
2017-10-30T08:31:44 PID[10332] Information Sending response: 200.0 OK
2017-10-30T08:31:44 PID[10332] Information Sending response: 200.0 OK
【问题讨论】:
这是什么 -http://IP_ADDR:8545.
?那是函数之外的某个地方还是本地主机?绑定到 localhost 上的任意端口在函数中不起作用。
我只是用 IP_ADDR 掩盖了错误日志中的实际 IP 地址,端口或 IP 没有问题。 Web3.providers.HttpProvider("IP_ADDR:8545");
如果它在 Kudu 上工作,它也应该在函数上工作。有点奇怪。如果在 Kudu 控制台中执行 curl -v http://IP_ADDR:8545
会得到什么?
curl 工作正常,连接到 IP 端口 8545,响应 HTTP/1.1 200 OK
堆栈跟踪指向 TCP 层以上的问题,可能在 HTTP 协议甚至上一层。你是如何curl
ing 那个 URL 的,你是否使用了一个秘密,也许是一个 API 密钥?会不会是函数读错了?您可以将您的 Function 指向类似 requestb.in 的内容,然后查看完整的请求,因为它来自网络。这样做时要小心秘密。
【参考方案1】:
以下是我解决此问题的步骤。
-
在应用服务计划(而不是消费计划)上创建 Azure Function App
启用 websocket
将运行时版本切换到 Beta
请注意,Websock 和运行时版本选项仅适用于应用服务计划。
【讨论】:
以上是关于在 Azure Function 上使用 web3.js 调用 Ethereum的主要内容,如果未能解决你的问题,请参考以下文章
在 Azure Function 上获取数据时,HttpClient.GetAsync() 会产生 AggregateException
Newtonsoft 11.0.0.0 无法在 Azure Function App 2.0 上加载
消费层上 Azure Function App 的白名单 IP
如何在 Visual Studio 中的不同端口上运行 Azure Function 应用程序