问题
I got an issue when invoke a contract call from Polkadot JS api.
If the function include HashMap insert() or BTreeMap insert() in contract, when call it via api, I'll get:
{"ApplyExtrinsic":1}
[ An extrinsic failed.]
{"index":"0x0001","data":[{"Other":null},{"weight":10000000000,"class":"Normal","paysFee":"Yes"}]}
Event won't be triggered correctly. But if I use HashMap/ BTreeMap get() or contains_key(), I can get event data correctly.
Here's my contract code in lib.rs:
/*
Using the standard library if we run the tests module,
or if we use a std feature flag within our code.
Otherwise the contract will always compile with no_std.
*/
#![cfg_attr(not(feature = "std"), no_std)]
extern crate hex;
use ink_lang as ink;
#[ink::contract(version = "0.1.0")]
mod roleContract {
#[cfg(not(feature = "ink-as-dependency"))]
use ink_core::storage;
use ink_core::storage::BTreeMap;
/// Defines the storage of your contract.
/// Add new fields to the below struct in order
/// to add new static storage fields to your contract.
#[ink(storage)]
struct RoleContract {
/// Stores a single `bool` value on the storage.
test_hashmap: storage::hash_map::HashMap<AccountId, u64>,
test_btreemap: storage::BTreeMap<AccountId, u64>,
}
#[ink(event)]
struct TestEvent {
#[ink(topic)]
isOk: u32,
}
impl RoleContract {
/// Constructor that initializes the caller as roleType = 1 (System)
#[ink(constructor)]
fn newRoleContract(&mut self) {}
/// Add caller type
#[ink(message)]
fn setType(&mut self) {
let bytes: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let acc = AccountId::from(bytes);
let default_value:u64 = 1;
// self.test_hashmap.insert(acc, default_value);
self.test_btreemap.insert(acc, default_value);
self.env()
.emit_event(
TestEvent {
isOk: 1,
}
);
}
}
}
And here's the js file for api call:
async function main() {
const provider = new WsProvider('ws://127.0.0.1:9944');
const api = await ApiPromise.create({ provider: provider, types: {
"Address": "AccountId",
"LookupSource": "AccountId"
} });
const BOB="5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty";
const ALICE = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
const keyring = new Keyring({ type: 'sr25519' });
const alice=keyring.addFromUri("//Alice");
const setTypeSelector="0xEE03889D"; //from abi
const contractAddress = "0x33b757c837aaf6946de25ca35046fadb62e99848c7fe1d106404cb02a298bcf7";
const callTx=api.tx.contracts.call(contractAddress, 0, 10000000000, setTypeSelector);
console.log(callTx.toString());
console.log(callTx.toHuman());
console.log(callTx.toRawType());
await callTx.signAndSend(alice, ({events=[], status}) => {
if(status.isInBlock) {
console.log("callTx (set caller's type) is in block");
events.forEach(({event, phase}) => {
console.log(event.toHuman());
console.log(phase.toString());
console.log(event.meta.documentation.toString());
console.log(event.toString());
if(event.section=="contracts" && event.method=="ContractExecution") {
console.log("contract returned from", event.data[0].toHex(), "with pub key value", event.data[1]);
}
});
} else {
console.log('\n', "callTx (set caller's type) waiting to be in block");
}
});
}
Anyone knows what the issue is?
来源:https://stackoverflow.com/questions/62601759/extrinsic-failed-when-invoke-hashmap-btreemap-insert-in-ink-contract-via-polk