智能合约收到的号码不正确

问题描述 投票:0回答:1

部署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;
}
npm blockchain telegram blueprint ton
1个回答
0
投票

返回以

1
开头的随机 11 位数字的问题可能与
Counter
智能合约持久存储中的未初始化或损坏状态有关。让我们逐步排查并解决问题:


1。验证初始状态

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 });
    }
    

2。部署重置

当您重新部署智能合约时,请确保区块链状态是干净的:

  1. 删除现有合约状态: 在重新部署之前,请使用网络工具删除旧合同或部署到新地址。

  2. 验证部署逻辑: 检查脚本或工具中的部署步骤,以确认它使用干净的存储设置了合同。


3.调试状态变化

了解为什么您会得到意想不到的值:

  1. 添加调试日志: 修改

    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);
    }
    
  2. 检查

    get_total
    确保该方法从持久存储中读取正确的值:

    int get_total() method_id {
        slice ds = get_data().begin_parse();
        return ds~load_uint(64);
    }
    
  3. 手动检查存储: 使用 TON 提供的工具(例如 CLI 或网络浏览器)在部署后和交易后检查合约的存储情况。


4。验证客户端调用

验证

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
并且在传输过程中不被更改。


5。隔离测试

在与系统的其余部分集成之前,独立测试合约:

  1. 部署新实例: 确保合约没有先前状态。

  2. 手动发送交易: 使用 TON CLI 工具通过

    recv_internal
    手动调用
    123
    并验证
    get_total
    的结果。

  3. 检查初始化问题: 确保

    get_total
    在部署之后和任何事务之前立即返回
    0


6。可能的原因

  • 未初始化状态:如果在部署期间未显式调用
    set_data
    ,则存储可能包含随机数据。
  • 不当重新部署:如果在未清除状态的情况下重复使用同一地址,旧数据可能会保留。
  • 不正确的有效负载:确保客户端(
    sendNumber
    )发送正确的号码和格式。

预期结果

应用这些修复后:

  1. get_total
    函数最初应返回
    0
  2. 使用
    sendNumber
    调用
    123
    后,
    get_total
    应返回
    123

如果问题仍然存在或者是否需要进一步的调试步骤,请告诉我!

© www.soinside.com 2019 - 2024. All rights reserved.