Blockchain 如何订阅“日志事件”并在ThunderCore上获取通知?
当我想订阅Blockchain 如何订阅“日志事件”并在ThunderCore上获取通知?,blockchain,smartcontracts,web3js,thundercore,Blockchain,Smartcontracts,Web3js,Thundercore,当我想订阅log事件并在ThunderCore上获得通知时,我遇到了一些问题 据我所知,似乎我应该使用websocket和。有什么例子吗 或者,还有其他解决方案可以实现我的目标吗?通过以下方式获取ThunderCore上新合同事件的通知: 使用到RPC节点的Websocket连接,例如 在日志事件上调用eth\u subscribeRPC方法 自足的例子 SimpleRecord.sol pragma solidity ^0.4.25; contract SimpleRecord {
log
事件并在ThunderCore上获得通知时,我遇到了一些问题
据我所知,似乎我应该使用websocket和。有什么例子吗
或者,还有其他解决方案可以实现我的目标吗?通过以下方式获取ThunderCore上新合同事件的通知:
日志
事件上调用eth\u subscribe
RPC方法SimpleRecord.sol
pragma solidity ^0.4.25;
contract SimpleRecord {
event Record(
address indexed _from,
uint _value
);
function write() payable public {
emit Record(msg.sender, msg.value);
}
}
要生成Record
事件,请运行simple Record write
查看运行的通知simple Record log subscribe
:
const process = require('process')
const path = require('path')
const fs = require('fs')
const Web3 = require('web3')
const Accounts = require('web3-eth-accounts')
const util = require('util')
// truffle migrate --reset --network thunder-mainnet
const thunderWsUrl = 'wss://mainnet-ws.thundercore.com'
// truffle migrate --reset --network thunder-testnet
//const thunderWsUrl = 'wss://testnet-ws.thundercore.com'
const programName = () => {
return path.basename(process.argv[1])
}
const web3Url = () => {
let u = process.env['WEB3_PROVIDER_URI']
if (u === undefined) {
u = thunderWsUrl
}
return u
}
const signTx = async (fromAccount, tx) => {
const signedTx = await fromAccount.signTransaction(tx)
return signedTx.rawTransaction // hex string
}
const setup = async () => {
const privateKeys = fs.readFileSync(path.join(__dirname, '..', '.private-keys'), {encoding: 'ascii'}).split('\n').filter(x => x.length > 0)
const accounts = new Accounts()
const account = accounts.privateKeyToAccount('0x' + privateKeys[0])
const jsonBuf = fs.readFileSync(path.join(__dirname, '..', 'build', 'contracts', 'SimpleRecord.json'))
const contractData = JSON.parse(jsonBuf)
const contractAbi = contractData['abi']
const web3ProviderUrl = web3Url()
const web3 = new Web3(web3ProviderUrl)
const networkId = await web3.eth.net.getId()
let deployedNetwork, contractAddress
try {
deployedNetwork = contractData['networks'][networkId]
contractAddress = deployedNetwork['address']
} catch (err) {
msg = `error getting deployedNetwork: ${err}`
throw new Error(msg)
}
const contract = new web3.eth.Contract(contractAbi, contractAddress)
return [ web3ProviderUrl, web3, networkId, contractAddress, contract, account ]
}
const prettyPrint = (o) => {
return util.inspect(o, {showHidden: false, depth: null, colors: true})
}
const recordWrite = async () => {
const [web3ProviderUrl, web3, chainId, contractAddress, contract, fromAccount] = await setup()
console.log('web3ProviderUrl:', web3ProviderUrl)
const txnData = contract.methods.write().encodeABI()
console.log('account.address:', fromAccount.address)
const promiseResults = await Promise.all([
web3.eth.getTransactionCount(fromAccount.address),
web3.eth.getGasPrice(),
])
const nonce = promiseResults[0]
const gasPrice = promiseResults[1]
const tx = {
'gasLimit': 0,
'chainId': chainId,
'gasPrice': gasPrice,
'nonce': Web3.utils.toHex(nonce),
'from': fromAccount.address,
'to': contractAddress,
'value': 0xbeef,
'data': txnData,
}
const gasMultiple = 2.0
tx.gasLimit = (await web3.eth.estimateGas(tx)) * gasMultiple
console.log('tx:', prettyPrint(tx))
const rawTxStr = await signTx(fromAccount, tx)
const r = await web3.eth.sendSignedTransaction(rawTxStr)
console.log('sendTransaction: receipt:', prettyPrint(r))
return 0
}
const logSubscribe = () => {
return new Promise((resolve, reject) => {
setup().then(([web3ProviderUrl, web3, chainId, contractAddress, contract, account]) => {
let eventCount = 0
console.log('web3ProviderUrl:', web3ProviderUrl)
console.log('contractAddress:', contractAddress)
console.log('contract.options.jsonInterface:', prettyPrint(contract.options.jsonInterface))
const eventAbis = contract.options.jsonInterface.filter((abiObj) => abiObj.type === 'event')
web3.eth.subscribe('logs', { address: contractAddress }, (err, log) => {
console.log('eth.subscribe("logs") callback')
if (err) {
console.log('logs callback, err:', err)
reject(err)
return
}
eventCount++
console.log(`log[${eventCount}]:`, log)
const eventSig = log.topics[0]
for (let abi of eventAbis) {
if (eventSig === abi.signature) {
const decoded = web3.eth.abi.decodeLog(abi.inputs, log.data, log.topics.slice(1))
console.log('Decoded Event:', prettyPrint(abi), '\n', prettyPrint(decoded))
resolve(0)
return
}
}
})
})
})
}
(async () => {
if (programName().endsWith('-write')) {
process.exit(await recordWrite())
} else if (programName().endsWith('-log-subscribe')) {
process.exit(await logSubscribe())
} else {
console.error(`unsupported program name: "${programName()}"`)
process.exit(2)
}
})()
查看
现场支持
repo的订阅日志
分支中的完整项目。listen\u thundercore\u mainnet.js
/**
*连接到Thundercore mainnet并收听特定智能合约地址的提示。
*/
const Web3=require('Web3');
var提供者wss://mainnet-ws.thundercore.com';
var web3=新的web3(提供者);
let listence=()=>{
//创建与Thundercore mainet的连接。
常量smartContractAddress='0xB7D82E5B73E01BB4C1C1CCFB1448F1215BF165929A2'
var subscription=web3.eth.subscripte('日志'{
地址:smartContractAddress,
},(错误、结果)=>{
如果(错误){
console.log(错误)
console.log('重新连接到Thundercore mainnet')
设置超时(()=>{
//如果连接断开,则需要重新实例化web3。
web3=新的web3(提供商);
_听
}, 5000);
}
})
.on('connected',(subscriptionId)=>{
console.log('已连接')
})
.on('数据',(日志)=>{
console.log(log);
})
.on(“已更改”,(日志)=>{
console.log('changed')
})
退订
}
const\u listen=async()=>{
让tips=listence();
console.log('连接到Thundercore mainnet')
//web3订阅在60秒时超时。在50秒时关闭并重新打开。
设置间隔(()=>{
提示:取消订阅((错误,成功)=>{
如果(错误){
console.log('未能从Thundercore mainnet断开连接!');
}
如果(成功){
console.log('disconnected');
}
});
tips=listence();
}, (50 * 1000));
}
_听
与NodeJS一起运行
节点侦听到\u thundercore\u mainnet.js
Thundercore会在60秒后断开您的连接。因此,我们在这之前故意断开连接,并立即重新连接。
这种方法在跟踪流量巨大的合同时会错过一些交易