Erfassen eines Ereignisses, das von einem Vertrag ausgelöst wurde, der von einem anderen Vertrag aufgerufen wurde

Ich versuche, Steuern auf beliebige Gegenstände/Werte zu berechnen. Dazu habe ich einen einzigen Vertrag, der als 'Oracle' verwendet wird, um die Steuer von einem externen System zu erhalten. Dieser Vertrag definiert Funktionen, die von anderen Verträgen aufgerufen werden sollen, und gibt ein Ereignis aus, das vom externen Code erfasst wird. Dieser führt dann die Berechnungen durch und sendet die Daten an den Vertrag zurück. Der Code ist

pragma solidity ^0.4.21;

contract TaxContract {
    address public owner;
    event TaxRequest(int price);

    constructor() public {
       owner = msg.sender;
    }

    function calculateTax(int price) public {
       emit TaxRequest(price);
    }
}

Dem aufrufenden Vertrag wird die Adresse des TaxContract in seinem Konstruktor übergeben.

pragma solidity ^0.4.21;

import "./TaxContract.sol";

// Asset Test Contract
contract AssetContract {
    address public owner;
    address contractAddress;

    // Constructor
    constructor(address taxContractAddress) public {
        owner = msg.sender;
        contractAddress = taxContractAddress;
    }

    // Public functions
    function sellAsset(int price) public {
        TaxContract(contractAddress).calculateTax(price);
    }
}

Ich verwende Nethereum, um sowohl die Verträge bereitzustellen als auch auf Ereignisse zu hören, dh

var sellFunction = contract.GetFunction("sellAsset");
var gasLimit = await sellFunction.EstimateGasAsync().ConfigureAwait(false);
await sellFunction.SendTransactionAndWaitForReceiptAsync(senderAddress, gasLimit, null, null, 563278);

und

var taxRequestEvent = contract.GetEvent("TaxRequest");
var taxFilter = await taxRequestEvent.CreateFilterAsync();

while (true)
{
var taxEvent = await taxRequestEvent.GetFilterChanges<SalesTaxRequestEvent>(taxFilter);
....

Als ich die gesamte Funktionalität in einem Vertrag hatte, dh die sellAsset-Methode das Ereignis ausgab, auf das der externe Code wartete, und die sellAsset-Funktion aufrief, funktionierte alles. Aber jetzt, wo ich es in zwei separate Verträge aufgeteilt habe, scheint kein Ereignis ausgelöst zu werden. Irgendwelche Ideen, warum das nicht funktioniert?

Antworten (2)

Abgesehen von einigen experimentellen Arbeiten, bei denen Assembler zum Untersuchen von Ereignisprotokollen verwendet wird, können Sie keine Ereignisprotokolle aus einem Vertrag lesen. Verträge, die interne Transaktionen (auch bekannt als Nachrichten) senden, können Rückgabewerte lesen. calculateTax()Erwägen Sie daher, die Funktion so zu ändern , dass sie "die Daten an den Vertrag zurücksenden" kann.

function calculateTax(int price) public returns(int) {
   emit TaxRequest(price);
   return price;
}

Dann inAssetContract

// Public functions
function sellAsset(int price) public {
    int tax = TaxContract(contractAddress).calculateTax(price);
}

Abgesehen davon denke ich, dass uintes funktionieren würde, es sei denn, Sie erwarten negative Steuersätze.

Ich hoffe es hilft.

Das habe ich wohl nicht richtig erklärt. Ich versuche, das Ereignis in einer externen Anwendung zu erfassen, die die Berechnung durchführt und die Daten wieder in die Kette einfügt. Dieser Code hilft also nicht.

Ich hatte eine ähnliche Situation wie Sie, in der ich Ereignisse erfassen musste, die durch einen Vertrag generiert wurden, der von meinem Anruferkontakt angerufen wurde.

Ich habe es gelöst, indem ich so GetAllChangesetwas verwendet habe:

var receipt = await sellFunction.SendTransactionAndWaitForReceiptAsync(senderAddress, gasLimit, null, null, 563278);
var taxRequestEvent = contract.GetEvent("TaxRequest");
var taxFilter = await taxRequestEvent.CreateFilterAsync( new BlockParameter(receipt.BlockNumber), new BlockParameter(receipt.BlockNumber));
var taxEvents = await taxRequestEvent.GetAllChanges<SalesTaxRequestEvent>(taxFilter);