NEAR智能合约调用报错:cannot read property 'prefix' of undefined
NEAR智能合约buy方法执行错误排查
错误信息
调用buy方法时触发以下执行错误:
ExecutionError: "Smart contract panicked: cannot read property 'prefix' of undefined" + ' at reconstruct (build/microsoft.js:994) ' + ' at _reconstruct (build/microsoft.js:1102) ' + ' at buy (build/microsoft.js:1137) '
原合约代码
import { NearBindgen, call, view, UnorderedMap, initialize } from 'near-sdk-js'; @NearBindgen({}) export class ExchangeContractMicrosoft { private stocks: UnorderedMap<number> = new UnorderedMap<number>( 'unique-id-map1', ); constructor() { this.stocks.set('msft', 10000000); } @call({}) buy(): void { const stock: string = 'msft'; this.checkStock(stock, 1); this.stocks.set('msft', this.stocks.get(stock) - 1); } private checkStock(stock: string, value: number): void { if (this.stocks.get(stock) < value) { throw 'Not enough stocks'; } } }
交互命令
near call sipars.testnet buy '{}' --accountId sipars.testnet --gas=300000000000000
问题原因及修复方案
问题根源
NEAR SDK-JS不支持通过类的构造函数初始化合约状态,构造函数不会在合约部署时被正确执行,导致stocks这个UnorderedMap未被实例化,调用buy方法时访问其属性就会触发undefined错误。
修复步骤
- 移除构造函数,改用带
@initialize()装饰器的初始化方法承载状态初始化逻辑 - 先声明
stocks属性,在初始化方法中完成实例化和初始值设置 - 部署新合约后,必须先调用初始化方法完成状态初始化
修复后的合约代码:
import { NearBindgen, call, view, UnorderedMap, initialize } from 'near-sdk-js'; @NearBindgen({}) export class ExchangeContractMicrosoft { private stocks: UnorderedMap<number>; @initialize({}) init(): void { this.stocks = new UnorderedMap<number>('unique-id-map1'); this.stocks.set('msft', 10000000); } @call({}) buy(): void { const stock: string = 'msft'; this.checkStock(stock, 1); this.stocks.set('msft', this.stocks.get(stock) - 1); } private checkStock(stock: string, value: number): void { if (this.stocks.get(stock) < value) { throw 'Not enough stocks'; } } }
后续操作
部署修复后的合约后,先执行初始化命令:
near call sipars.testnet init '{}' --accountId sipars.testnet
之后再调用buy方法即可正常执行。
内容的提问来源于stack exchange,提问作者Parshant Singh
相关产品推荐
相关产品推荐

