部署sendNumber.ts脚本时
import { toNano } from 'ton-core';
import { Counter } from '../wrappers/Counter';
import { compile, NetworkProvider } from '@ton-community/blueprint';
export async function run(provider: NetworkProvider) {
const counter = provider.open(
Counter.createFromConfig({}, await compile('Counter'))
);
await counter.sendNumber(provider.sender(), toNano('0.01'), 123n);
console.log('Sent number: ', await counter.getTotal());
}
跑步时
npx blueprint run
我得到的返回值为
"Sent number: 15322573764n"
它应该在的地方
Sent number: 123n
将智能合约重置为 0 并再次重新部署后,我再次得到一个随机数
以1开头的11位数字
这里是函数定义“Counter.ts”的包装代码:
export class Counter implements Contract {
constructor(
readonly address: Address,
readonly init?: { code: Cell; data: Cell }
) {}
...................
async sendNumber(
provider: ContractProvider,
via: Sender,
value: bigint,
number: bigint
) {
await provider.internal(via, {
value,
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: beginCell().storeUint(number, 32).endCell(),
});
}
counter.fc(据我所知这里没有错误)
#include "imports/stdlib.fc";
() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
throw_if(35, in_msg_body.slice_bits() < 32);
int n = in_msg_body~load_uint(32);
slice ds = get_data().begin_parse();
int total = ds~load_uint(64);
total += n;
set_data(begin_cell().store_uint(total, 64).end_cell());
}
int get_total() method_id {
slice ds = get_data().begin_parse();
int total = ds~load_uint(64);
return total;
}
返回以
1
开头的随机 11 位数字的问题可能与 Counter
智能合约持久存储中的未初始化或损坏状态有关。让我们逐步排查并解决问题:
Counter
合约的存储(set_data
)应该以正确初始化的值开始,例如0
。如果在部署期间未显式初始化存储,则它可能包含随机垃圾数据。
查看合约初始化代码: 确保您的部署脚本将合约的存储初始化为
0
。例如:
int initial_value = 0;
set_data(begin_cell().store_uint(initial_value, 64).end_cell());
修改
Counter
包装器:
在 Counter.ts
中,确保 createFromConfig
在部署期间显式设置初始状态:
static createFromConfig(config: {}, code: Cell) {
const data = beginCell().storeUint(0, 64).endCell(); // Initialize storage to 0
return new Counter(contractAddress, { code, data });
}
当您重新部署智能合约时,请确保区块链状态是干净的:
删除现有合约状态: 在重新部署之前,请使用网络工具删除旧合同或部署到新地址。
验证部署逻辑: 检查脚本或工具中的部署步骤,以确认它使用干净的存储设置了合同。
了解为什么您会得到意想不到的值:
添加调试日志: 修改
recv_internal
函数以包含调试消息:
() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
throw_if(35, in_msg_body.slice_bits() < 32);
int n = in_msg_body~load_uint(32);
slice ds = get_data().begin_parse();
int total = ds~load_uint(64);
debug("Current Total: ", total);
debug("Adding: ", n);
total += n;
set_data(begin_cell().store_uint(total, 64).end_cell());
debug("New Total: ", total);
}
检查
get_total
:
确保该方法从持久存储中读取正确的值:
int get_total() method_id {
slice ds = get_data().begin_parse();
return ds~load_uint(64);
}
手动检查存储: 使用 TON 提供的工具(例如 CLI 或网络浏览器)在部署后和交易后检查合约的存储情况。
验证
sendNumber
方法正在发送正确的有效负载:
async sendNumber(
provider: ContractProvider,
via: Sender,
value: bigint,
number: bigint
) {
console.log("Sending number:", number);
await provider.internal(via, {
value,
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: beginCell().storeUint(number, 32).endCell(),
});
}
确保
number
为 123n
并且在传输过程中不被更改。
在与系统的其余部分集成之前,独立测试合约:
部署新实例: 确保合约没有先前状态。
手动发送交易: 使用 TON CLI 工具通过
recv_internal
手动调用 123
并验证 get_total
的结果。
检查初始化问题: 确保
get_total
在部署之后和任何事务之前立即返回 0
。
set_data
,则存储可能包含随机数据。sendNumber
)发送正确的号码和格式。应用这些修复后:
get_total
函数最初应返回0
。sendNumber
调用 123
后,get_total
应返回 123
。如果问题仍然存在或者是否需要进一步的调试步骤,请告诉我!