Sputnik v2创建合约提示account不存在,添加账户无效的NEAR SDK迁移问题
问题根因分析
- 你替换空字符串为
base.token符合NEAR AccountId合法性要求,但NEAR单元测试环境的默认创世配置没有预先创建这个账户,也没有部署对应合约代码,才会触发两次报错:第一次是账户不存在,第二次是你将它设为根账户但未部署对应合约,因此触发找不到合约代码的错误。 - 你直接创建
base.token子账户报错的原因是NEAR子账户必须由它的上级账户(也就是token账户)签名创建,没有上级签名直接创建子账户不符合规则。
解决方案
1. 优先使用合法顶级账户作为测试用Token ID
不用base.token这类子账户格式,改用test-token这种符合AccountId规则的顶级账户名,避免子账户创建依赖,直接替换原来的空字符串即可。
2. 常量AccountId的兼容方案
NEAR SDK v4提供了const AccountId::new_unchecked方法,可直接用于常量声明,不需要运行时构造,替换原来的空字符串常量即可:
const TOKEN_ID: AccountId = AccountId::new_unchecked("test-token");
注意:new_unchecked方法仅推荐在测试环境或者你100%确认账户名合法的场景下使用,生产环境建议用AccountId::try_from做合法性校验
3. 必须使用base.token的调整方案
如果业务要求必须使用base.token作为账户名,按以下步骤修改测试代码:
第一步:按子账户规则创建base.token
// 先创建上级token账户 let token_account = env::create_account( AccountId::new_unchecked("token".to_string()), 10u128.pow(24), // 配置初始NEAR余额 ); // 用token账户签名创建base.token子账户 let base_token_account = token_account.create_subaccount( AccountId::new_unchecked("base.token".to_string()), 10u128.pow(24), );
第二步:给base.token部署对应合约
如果base.token是FT合约账户,需要给该账户部署对应FT合约字节码:
base_token_account.deploy(ft_contract_wasm().to_vec());
第三步:调整创世配置逻辑
你之前修改根账户为base.token的逻辑需要补充合约注册操作,避免找不到合约报错:
let mut gen_cfg = GenesisConfig::default(); let base_token_id = base_token(); gen_cfg.init_root_signer(base_token_id.as_str()); // 给base.token账户注册对应合约代码 gen_cfg.register_contract(base_token_id.as_str(), ft_contract_wasm());
内容的提问来源于stack exchange,提问作者Rashi Abramson
相关产品推荐
相关产品推荐

