tact icon indicating copy to clipboard operation
tact copied to clipboard

Send remaining value error after emit event

Open xfhxfh2021 opened this issue 1 year ago • 2 comments

Exit code 37 comes out when I use SendRemainingValue after emit event. For example:


fun sendRemaingValue() {
  emit(TransferEvent{amount: ton("1.25"), recipient: sender()}.toCell());
  
  send(SendParameters{
        to: account,
        value: 0,
        bounce: false,
        mode: SendRemainingValue,
        body: TransferSuccess {
                amount: ton("1.25"), 
                recipient: sender()
            }.toCell()
    });
}

xfhxfh2021 avatar Apr 22 '24 09:04 xfhxfh2021

@xfhxfh2021 Thanks for your report. Could you please provide an MRE? That would help us immensely.

anton-trunov avatar Apr 22 '24 10:04 anton-trunov

@xfhxfh2021 Thanks for your report. Could you please provide an MRE? That would help us immensely.

test_transfer.tact

import "@stdlib/deploy";

message TestEvent {
    amount: Int;
    recipient: Address;
}

struct TransferSuccess {
    amount: Int;
    recipient: Address;
}

contract TestTransfer with Deployable {
    init() {
        
    }

    receive("SendRemainValue") {
        emit(TestEvent{amount: context().value, recipient: myAddress()}.toCell());
        
        send(SendParameters{
            to: sender(),
            value: 0,
            bounce: false,
            mode: SendRemainingValue,
            body: TransferSuccess {
                amount: context().value, 
                recipient: myAddress()
            }.toCell()
        });
    }
}

Test.spec.ts

import { Blockchain, printTransactionFees, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { toNano } from '@ton/core';
import { TestTransfer } from '../wrappers/TestTransfer';
import '@ton/test-utils';

describe('TestTransfer', () => {
    let blockchain: Blockchain;
    let deployer: SandboxContract<TreasuryContract>;
    let testTransfer: SandboxContract<TestTransfer>;

    beforeEach(async () => {
        blockchain = await Blockchain.create();

        testTransfer = blockchain.openContract(await TestTransfer.fromInit());

        deployer = await blockchain.treasury('deployer');

        const deployResult = await testTransfer.send(
            deployer.getSender(),
            {
                value: toNano('0.05'),
            },
            {
                $$type: 'Deploy',
                queryId: 0n,
            }
        );

        expect(deployResult.transactions).toHaveTransaction({
            from: deployer.address,
            to: testTransfer.address,
            deploy: true,
            success: true,
        });
    });

    it('should deploy', async () => {
        // the check is done inside beforeEach
        // blockchain and testTransfer are ready to use
    });

    it('should send failed', async () => {
        const deployResult = await testTransfer.send(
            deployer.getSender(),
            {
                value: toNano('0.05'),
            },
            'SendRemainValue'
        );
        printTransactionFees(deployResult.transactions);
    });


});

xfhxfh2021 avatar Apr 22 '24 11:04 xfhxfh2021

Up Instead of exit code 37, emitting logs causes the message sent with SendRemainingValue to be simply ignored

Shchepetov avatar Sep 01 '24 23:09 Shchepetov

This is expected behavior: please read this explanation https://docs.tact-lang.org/book/send#outbound-message-processing

anton-trunov avatar Sep 02 '24 06:09 anton-trunov

It's probably worth adding that emit essentially sends a message, so the explanation above applies to this case too

anton-trunov avatar Sep 02 '24 06:09 anton-trunov