函数 getAccountBalance() 不起作用
Function getAccountBalance() doesn't work
我正在创建示例以与其他开发人员分享,但我现在尽量保持代码非常简单,所有基本功能都可以正常工作:
我使用的是官方文档LINK
account.deleteAccount()
account.getAccountDetails()
account.createAccount()
等等...但是这个函数:
account.getAccountBalance();
向我发送错误消息:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading "storage_amount _per_byte" )
at Account.getAccountBalance (VM3453 near-api-is.is:346)
at async main.is: 46
+++++更新++++++
const CONTRACT_NAME = 'josedlujan.testnet'; /* TODO: fill this in! */
const config = {
nodeUrl: "https://rpc.testnet.near.org",
//deps: {
keyStore: new nearApi.keyStores.BrowserLocalStorageKeyStore(),
//},
networkId: 'testnet',
nodeUrl: 'https://rpc.testnet.near.org',
contractName: CONTRACT_NAME,
walletUrl: 'https://wallet.testnet.near.org',
helperUrl: 'https://helper.testnet.near.org'
};
async function () {
window.near = await nearApi.connect(config);
console.log(near)
// ---------------------------------------------------------------------------
// here you have access to `near-api-js` and a valid connection object `near`
// ---------------------------------------------------------------------------
window.walletConnection = new nearApi.WalletConnection(near);
console.log(window.walletConnection)
// Initializing our contract APIs by contract name and configuration.
window.contract = await new nearApi.Contract(window.walletConnection.account(), near.contractName, {
// View methods are read-only – they don't modify the state, but usually return some value
viewMethods: ['get_num'],
// Change methods can modify the state, but you don't receive the returned value when called
changeMethods: ['increment', 'decrement', 'reset'],
// Sender is the account ID to initialize transactions.
// getAccountId() will return empty string if user is still unauthorized
sender: window.walletConnection.getAccountId()
});
window.account = await near.account(walletConnection.getAccountId());
console.log(window.account);
const balance = await window.account.getAccountBalance();
console.log(balance);
在试图了解可能发生故障的同时,这就是我所做的...
(1)看源码
这是您调用该方法时 运行 的代码。我通过在 near-api-js
存储库中搜索字符串“getAccountBalance”找到了它,因为我看到你在 JavaScript 上下文中是 运行,而且我知道 NEAR 包装了它的 API near-api-js
让 JavaScript 开发者的生活更轻松。
async getAccountBalance(): Promise < AccountBalance > {
const protocolConfig = await this.connection.provider.experimental_protocolConfig({ finality: 'final' });
const state = await this.state();
const costPerByte = new BN(protocolConfig.runtime_config.storage_amount_per_byte);
const stateStaked = new BN(state.storage_usage).mul(costPerByte);
const staked = new BN(state.locked);
const totalBalance = new BN(state.amount).add(staked);
const availableBalance = totalBalance.sub(BN.max(staked, stateStaked));
return {
total: totalBalance.toString(),
stateStaked: stateStaked.toString(),
staked: staked.toString(),
available: availableBalance.toString()
};
}
函数中第一行调用experimental_protocolConfig
await this.connection.provider.experimental_protocolConfig({ finality: 'final' });
(2) 分段测试
我可以获取此函数的每个部分并从 NEAR CLI 中可用的 REPL 中一个一个地调用它并检查它是什么 returns
首先,在上下文中使用您的帐户启动 repl
near repl --accountId sherif.testnet
然后,调用方法
await account.getAccountBalance()
结果对我来说很好
{
total: '21795471561668895374325524265',
stateStaked: '212510000000000000000000',
staked: '0',
available: '21795259051668895374325524265'
}
然后,调用方法
await account.connection.provider.experimental_protocolConfig({ finality: 'final'})
你会看到 return 值
{
"protocol_version": 50,
"genesis_time": "2020-07-31T03:39:42.911378Z",
"chain_id": "testnet",
"genesis_height": 42376888,
"num_block_producer_seats": 200,
"num_block_producer_seats_per_shard": [
200,
200,
200,
200
],
"avg_hidden_validator_seats_per_shard": [
0,
0,
0,
0
],
"dynamic_resharding": false,
"protocol_upgrade_stake_threshold": [
4,
5
],
"epoch_length": 43200,
"gas_limit": 1000000000000000,
"min_gas_price": "5000",
"max_gas_price": "10000000000000000000000",
"block_producer_kickout_threshold": 80,
"chunk_producer_kickout_threshold": 90,
"online_min_threshold": [
90,
100
],
"online_max_threshold": [
99,
100
],
"gas_price_adjustment_rate": [
1,
100
],
"runtime_config": {
"storage_amount_per_byte": "10000000000000000000",
"transaction_costs": {
"action_receipt_creation_config": {
"send_sir": 108059500000,
"send_not_sir": 108059500000,
"execution": 108059500000
},
"data_receipt_creation_config": {
"base_cost": {
"send_sir": 36486732312,
"send_not_sir": 36486732312,
"execution": 36486732312
},
"cost_per_byte": {
"send_sir": 17212011,
"send_not_sir": 17212011,
"execution": 17212011
}
},
"action_creation_config": {
"create_account_cost": {
"send_sir": 99607375000,
"send_not_sir": 99607375000,
"execution": 99607375000
},
"deploy_contract_cost": {
"send_sir": 184765750000,
"send_not_sir": 184765750000,
"execution": 184765750000
},
"deploy_contract_cost_per_byte": {
"send_sir": 6812999,
"send_not_sir": 6812999,
"execution": 6812999
},
"function_call_cost": {
"send_sir": 2319861500000,
"send_not_sir": 2319861500000,
"execution": 2319861500000
},
"function_call_cost_per_byte": {
"send_sir": 2235934,
"send_not_sir": 2235934,
"execution": 2235934
},
"transfer_cost": {
"send_sir": 115123062500,
"send_not_sir": 115123062500,
"execution": 115123062500
},
"stake_cost": {
"send_sir": 141715687500,
"send_not_sir": 141715687500,
"execution": 102217625000
},
"add_key_cost": {
"full_access_cost": {
"send_sir": 101765125000,
"send_not_sir": 101765125000,
"execution": 101765125000
},
"function_call_cost": {
"send_sir": 102217625000,
"send_not_sir": 102217625000,
"execution": 102217625000
},
"function_call_cost_per_byte": {
"send_sir": 1925331,
"send_not_sir": 1925331,
"execution": 1925331
}
},
"delete_key_cost": {
"send_sir": 94946625000,
"send_not_sir": 94946625000,
"execution": 94946625000
},
"delete_account_cost": {
"send_sir": 147489000000,
"send_not_sir": 147489000000,
"execution": 147489000000
}
},
"storage_usage_config": {
"num_bytes_account": 100,
"num_extra_bytes_record": 40
},
"burnt_gas_reward": [
3,
10
],
"pessimistic_gas_price_inflation_ratio": [
103,
100
]
},
"wasm_config": {
"ext_costs": {
"base": 264768111,
"contract_compile_base": 35445963,
"contract_compile_bytes": 216750,
"read_memory_base": 2609863200,
"read_memory_byte": 3801333,
"write_memory_base": 2803794861,
"write_memory_byte": 2723772,
"read_register_base": 2517165186,
"read_register_byte": 98562,
"write_register_base": 2865522486,
"write_register_byte": 3801564,
"utf8_decoding_base": 3111779061,
"utf8_decoding_byte": 291580479,
"utf16_decoding_base": 3543313050,
"utf16_decoding_byte": 163577493,
"sha256_base": 4540970250,
"sha256_byte": 24117351,
"keccak256_base": 5879491275,
"keccak256_byte": 21471105,
"keccak512_base": 5811388236,
"keccak512_byte": 36649701,
"ripemd160_base": 853675086,
"ripemd160_block": 680107584,
"ecrecover_base": 278821988457,
"log_base": 3543313050,
"log_byte": 13198791,
"storage_write_base": 64196736000,
"storage_write_key_byte": 70482867,
"storage_write_value_byte": 31018539,
"storage_write_evicted_byte": 32117307,
"storage_read_base": 56356845750,
"storage_read_key_byte": 30952533,
"storage_read_value_byte": 5611005,
"storage_remove_base": 53473030500,
"storage_remove_key_byte": 38220384,
"storage_remove_ret_value_byte": 11531556,
"storage_has_key_base": 54039896625,
"storage_has_key_byte": 30790845,
"storage_iter_create_prefix_base": 0,
"storage_iter_create_prefix_byte": 0,
"storage_iter_create_range_base": 0,
"storage_iter_create_from_byte": 0,
"storage_iter_create_to_byte": 0,
"storage_iter_next_base": 0,
"storage_iter_next_key_byte": 0,
"storage_iter_next_value_byte": 0,
"touching_trie_node": 16101955926,
"promise_and_base": 1465013400,
"promise_and_per_promise": 5452176,
"promise_return": 560152386,
"validator_stake_base": 911834726400,
"validator_total_stake_base": 911834726400
},
"grow_mem_cost": 1,
"regular_op_cost": 822756,
"limit_config": {
"max_gas_burnt": 200000000000000,
"max_stack_height": 16384,
"stack_limiter_version": 1,
"initial_memory_pages": 1024,
"max_memory_pages": 2048,
"registers_memory_limit": 1073741824,
"max_register_size": 104857600,
"max_number_registers": 100,
"max_number_logs": 100,
"max_total_log_length": 16384,
"max_total_prepaid_gas": 300000000000000,
"max_actions_per_receipt": 100,
"max_number_bytes_method_names": 2000,
"max_length_method_name": 256,
"max_arguments_length": 4194304,
"max_length_returned_data": 4194304,
"max_contract_size": 4194304,
"max_transaction_size": 4194304,
"max_length_storage_key": 4194304,
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000
}
},
"account_creation_config": {
"min_allowed_top_level_account_length": 32,
"registrar_account_id": "registrar"
}
},
"transaction_validity_period": 86400,
"protocol_reward_rate": [
1,
10
],
"max_inflation_rate": [
1,
20
],
"num_blocks_per_year": 31536000,
"protocol_treasury_account": "near",
"fishermen_threshold": "340282366920938463463374607431768211455",
"minimum_stake_divisor": 10
}
看起来 storage_amount_per_byte
正如预期的那样就在 runtime_config
下面。
结论
不确定你的代码发生了什么,但这对我来说似乎工作得很好
我找到了解决方案。问题是文档是一些文档引用了 API 的不同版本,我查阅的第一个文档使用 API 36 显示错误,在另一个示例中,当我粘贴到屏幕上时,它们使用版本 41:
我不得不自己寻找最后一个 ncd 并使用版本 44。LINK
建议始终注意某些文档的版本需要更新。
当您发现变量值不是请求的参数的特定错误时要小心,因为您使用的文档很可能没有更新,感谢 Sherif 和 John 的支持。
我正在创建示例以与其他开发人员分享,但我现在尽量保持代码非常简单,所有基本功能都可以正常工作:
我使用的是官方文档LINK
account.deleteAccount()
account.getAccountDetails()
account.createAccount()
等等...但是这个函数:
account.getAccountBalance();
向我发送错误消息:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading "storage_amount _per_byte" )
at Account.getAccountBalance (VM3453 near-api-is.is:346)
at async main.is: 46
+++++更新++++++
const CONTRACT_NAME = 'josedlujan.testnet'; /* TODO: fill this in! */
const config = {
nodeUrl: "https://rpc.testnet.near.org",
//deps: {
keyStore: new nearApi.keyStores.BrowserLocalStorageKeyStore(),
//},
networkId: 'testnet',
nodeUrl: 'https://rpc.testnet.near.org',
contractName: CONTRACT_NAME,
walletUrl: 'https://wallet.testnet.near.org',
helperUrl: 'https://helper.testnet.near.org'
};
async function () {
window.near = await nearApi.connect(config);
console.log(near)
// ---------------------------------------------------------------------------
// here you have access to `near-api-js` and a valid connection object `near`
// ---------------------------------------------------------------------------
window.walletConnection = new nearApi.WalletConnection(near);
console.log(window.walletConnection)
// Initializing our contract APIs by contract name and configuration.
window.contract = await new nearApi.Contract(window.walletConnection.account(), near.contractName, {
// View methods are read-only – they don't modify the state, but usually return some value
viewMethods: ['get_num'],
// Change methods can modify the state, but you don't receive the returned value when called
changeMethods: ['increment', 'decrement', 'reset'],
// Sender is the account ID to initialize transactions.
// getAccountId() will return empty string if user is still unauthorized
sender: window.walletConnection.getAccountId()
});
window.account = await near.account(walletConnection.getAccountId());
console.log(window.account);
const balance = await window.account.getAccountBalance();
console.log(balance);
在试图了解可能发生故障的同时,这就是我所做的...
(1)看源码
这是您调用该方法时 运行 的代码。我通过在 near-api-js
存储库中搜索字符串“getAccountBalance”找到了它,因为我看到你在 JavaScript 上下文中是 运行,而且我知道 NEAR 包装了它的 API near-api-js
让 JavaScript 开发者的生活更轻松。
async getAccountBalance(): Promise < AccountBalance > {
const protocolConfig = await this.connection.provider.experimental_protocolConfig({ finality: 'final' });
const state = await this.state();
const costPerByte = new BN(protocolConfig.runtime_config.storage_amount_per_byte);
const stateStaked = new BN(state.storage_usage).mul(costPerByte);
const staked = new BN(state.locked);
const totalBalance = new BN(state.amount).add(staked);
const availableBalance = totalBalance.sub(BN.max(staked, stateStaked));
return {
total: totalBalance.toString(),
stateStaked: stateStaked.toString(),
staked: staked.toString(),
available: availableBalance.toString()
};
}
函数中第一行调用experimental_protocolConfig
await this.connection.provider.experimental_protocolConfig({ finality: 'final' });
(2) 分段测试
我可以获取此函数的每个部分并从 NEAR CLI 中可用的 REPL 中一个一个地调用它并检查它是什么 returns
首先,在上下文中使用您的帐户启动 repl
near repl --accountId sherif.testnet
然后,调用方法
await account.getAccountBalance()
结果对我来说很好
{
total: '21795471561668895374325524265',
stateStaked: '212510000000000000000000',
staked: '0',
available: '21795259051668895374325524265'
}
然后,调用方法
await account.connection.provider.experimental_protocolConfig({ finality: 'final'})
你会看到 return 值
{
"protocol_version": 50,
"genesis_time": "2020-07-31T03:39:42.911378Z",
"chain_id": "testnet",
"genesis_height": 42376888,
"num_block_producer_seats": 200,
"num_block_producer_seats_per_shard": [
200,
200,
200,
200
],
"avg_hidden_validator_seats_per_shard": [
0,
0,
0,
0
],
"dynamic_resharding": false,
"protocol_upgrade_stake_threshold": [
4,
5
],
"epoch_length": 43200,
"gas_limit": 1000000000000000,
"min_gas_price": "5000",
"max_gas_price": "10000000000000000000000",
"block_producer_kickout_threshold": 80,
"chunk_producer_kickout_threshold": 90,
"online_min_threshold": [
90,
100
],
"online_max_threshold": [
99,
100
],
"gas_price_adjustment_rate": [
1,
100
],
"runtime_config": {
"storage_amount_per_byte": "10000000000000000000",
"transaction_costs": {
"action_receipt_creation_config": {
"send_sir": 108059500000,
"send_not_sir": 108059500000,
"execution": 108059500000
},
"data_receipt_creation_config": {
"base_cost": {
"send_sir": 36486732312,
"send_not_sir": 36486732312,
"execution": 36486732312
},
"cost_per_byte": {
"send_sir": 17212011,
"send_not_sir": 17212011,
"execution": 17212011
}
},
"action_creation_config": {
"create_account_cost": {
"send_sir": 99607375000,
"send_not_sir": 99607375000,
"execution": 99607375000
},
"deploy_contract_cost": {
"send_sir": 184765750000,
"send_not_sir": 184765750000,
"execution": 184765750000
},
"deploy_contract_cost_per_byte": {
"send_sir": 6812999,
"send_not_sir": 6812999,
"execution": 6812999
},
"function_call_cost": {
"send_sir": 2319861500000,
"send_not_sir": 2319861500000,
"execution": 2319861500000
},
"function_call_cost_per_byte": {
"send_sir": 2235934,
"send_not_sir": 2235934,
"execution": 2235934
},
"transfer_cost": {
"send_sir": 115123062500,
"send_not_sir": 115123062500,
"execution": 115123062500
},
"stake_cost": {
"send_sir": 141715687500,
"send_not_sir": 141715687500,
"execution": 102217625000
},
"add_key_cost": {
"full_access_cost": {
"send_sir": 101765125000,
"send_not_sir": 101765125000,
"execution": 101765125000
},
"function_call_cost": {
"send_sir": 102217625000,
"send_not_sir": 102217625000,
"execution": 102217625000
},
"function_call_cost_per_byte": {
"send_sir": 1925331,
"send_not_sir": 1925331,
"execution": 1925331
}
},
"delete_key_cost": {
"send_sir": 94946625000,
"send_not_sir": 94946625000,
"execution": 94946625000
},
"delete_account_cost": {
"send_sir": 147489000000,
"send_not_sir": 147489000000,
"execution": 147489000000
}
},
"storage_usage_config": {
"num_bytes_account": 100,
"num_extra_bytes_record": 40
},
"burnt_gas_reward": [
3,
10
],
"pessimistic_gas_price_inflation_ratio": [
103,
100
]
},
"wasm_config": {
"ext_costs": {
"base": 264768111,
"contract_compile_base": 35445963,
"contract_compile_bytes": 216750,
"read_memory_base": 2609863200,
"read_memory_byte": 3801333,
"write_memory_base": 2803794861,
"write_memory_byte": 2723772,
"read_register_base": 2517165186,
"read_register_byte": 98562,
"write_register_base": 2865522486,
"write_register_byte": 3801564,
"utf8_decoding_base": 3111779061,
"utf8_decoding_byte": 291580479,
"utf16_decoding_base": 3543313050,
"utf16_decoding_byte": 163577493,
"sha256_base": 4540970250,
"sha256_byte": 24117351,
"keccak256_base": 5879491275,
"keccak256_byte": 21471105,
"keccak512_base": 5811388236,
"keccak512_byte": 36649701,
"ripemd160_base": 853675086,
"ripemd160_block": 680107584,
"ecrecover_base": 278821988457,
"log_base": 3543313050,
"log_byte": 13198791,
"storage_write_base": 64196736000,
"storage_write_key_byte": 70482867,
"storage_write_value_byte": 31018539,
"storage_write_evicted_byte": 32117307,
"storage_read_base": 56356845750,
"storage_read_key_byte": 30952533,
"storage_read_value_byte": 5611005,
"storage_remove_base": 53473030500,
"storage_remove_key_byte": 38220384,
"storage_remove_ret_value_byte": 11531556,
"storage_has_key_base": 54039896625,
"storage_has_key_byte": 30790845,
"storage_iter_create_prefix_base": 0,
"storage_iter_create_prefix_byte": 0,
"storage_iter_create_range_base": 0,
"storage_iter_create_from_byte": 0,
"storage_iter_create_to_byte": 0,
"storage_iter_next_base": 0,
"storage_iter_next_key_byte": 0,
"storage_iter_next_value_byte": 0,
"touching_trie_node": 16101955926,
"promise_and_base": 1465013400,
"promise_and_per_promise": 5452176,
"promise_return": 560152386,
"validator_stake_base": 911834726400,
"validator_total_stake_base": 911834726400
},
"grow_mem_cost": 1,
"regular_op_cost": 822756,
"limit_config": {
"max_gas_burnt": 200000000000000,
"max_stack_height": 16384,
"stack_limiter_version": 1,
"initial_memory_pages": 1024,
"max_memory_pages": 2048,
"registers_memory_limit": 1073741824,
"max_register_size": 104857600,
"max_number_registers": 100,
"max_number_logs": 100,
"max_total_log_length": 16384,
"max_total_prepaid_gas": 300000000000000,
"max_actions_per_receipt": 100,
"max_number_bytes_method_names": 2000,
"max_length_method_name": 256,
"max_arguments_length": 4194304,
"max_length_returned_data": 4194304,
"max_contract_size": 4194304,
"max_transaction_size": 4194304,
"max_length_storage_key": 4194304,
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000
}
},
"account_creation_config": {
"min_allowed_top_level_account_length": 32,
"registrar_account_id": "registrar"
}
},
"transaction_validity_period": 86400,
"protocol_reward_rate": [
1,
10
],
"max_inflation_rate": [
1,
20
],
"num_blocks_per_year": 31536000,
"protocol_treasury_account": "near",
"fishermen_threshold": "340282366920938463463374607431768211455",
"minimum_stake_divisor": 10
}
看起来 storage_amount_per_byte
正如预期的那样就在 runtime_config
下面。
结论
不确定你的代码发生了什么,但这对我来说似乎工作得很好
我找到了解决方案。问题是文档是一些文档引用了 API 的不同版本,我查阅的第一个文档使用 API 36 显示错误,在另一个示例中,当我粘贴到屏幕上时,它们使用版本 41:
建议始终注意某些文档的版本需要更新。
当您发现变量值不是请求的参数的特定错误时要小心,因为您使用的文档很可能没有更新,感谢 Sherif 和 John 的支持。