Developers Forum for XinFin XDC Network

Harshavardhan Gurram
Harshavardhan Gurram

Posted on

Issue with contract interaction from "Xinfin Remix IDE"

I've tried to deploy MultisigContract shown below through Xinfin Remix (https://remix.xinfin.network/) and also Remix IDE (https://remix.ethereum.org/).

Deployment is sucessful, but when it comes to interaction with one of the methods, say submitTransaction, gives below popup and error in Xinfin whether it's working fine on Remix IDE.

Popup Warning after invoking submitTransaction method.

Error Debug Log Part 1
Error Debug Log Part 2

I request someone who has encountered this previously or who has experience in the same to help us out.
Thanks in advance.

Below is the contract code:
`pragma solidity ^0.8.7;

contract Multisig {
//enum test{Accepted,Rejected,Pending}
struct Transaction {
bool executed;
bool accepted;
address destination;
uint value;
}

event Deposit(address indexed sender, uint value);
event Submission(uint indexed transactionId);
event Confirmation(address indexed sender, uint indexed transactionId);
event Execution(uint indexed transactionId);
event ExecutionFailure(uint indexed transactionId);

/// @dev Fallback function allows to deposit ether.
Enter fullscreen mode Exit fullscreen mode

fallback() external payable
{
if (msg.value > 0) {
emit Deposit(msg.sender, msg.value);
}
}

/*
 * Public functions
 */

address[] public owners;
uint public required;
mapping (address => bool) public isOwner;

uint public transactionCount;
mapping (uint => Transaction) public transactions;

mapping (uint => mapping (address => bool)) public confirmations;

mapping (uint => mapping (address => bool)) public acceptance;

constructor(address[] memory _owners, uint _required) public payable
    validRequirement(_owners.length,_required) {
    for (uint i=0; i<_owners.length; i++) {
        isOwner[_owners[i]] = true;
    }
    owners = _owners;
    required = _required;
}

modifier validRequirement(uint ownerCount, uint _required) {
    if (_required > ownerCount || _required == 0 || ownerCount == 0)
        revert();
    _;
}  

// @dev Allows an owner to submit and confirm a transaction.
// @param destination Transaction target address.
// @param value Transaction ether value.
// @param data Transaction data payload.
// @return Returns transaction ID.
//function submitTransaction(address destination, uint value, bytes memory data) public returns (uint transactionId) {}

function submitTransaction(address destination, uint value) 
    public payable
    returns (uint transactionId) 
{
    require(isOwner[msg.sender]);
    transactionId = addTransaction(destination, value);
    confirmTransaction(transactionId);
}

/// @dev Allows an owner to confirm a transaction.
/// @param transactionId Transaction ID.
function confirmTransaction(uint transactionId)
    public
{
    require(isOwner[msg.sender]);
    require(transactions[transactionId].destination != address(0));
    require(confirmations[transactionId][msg.sender] == false);
    confirmations[transactionId][msg.sender] = true;
    // Transaction.testing[msg.sender] = true;
    acceptance[transactionId][msg.sender] = true;
    emit Confirmation(msg.sender, transactionId);
    executeTransaction(transactionId);
}
Enter fullscreen mode Exit fullscreen mode

function confirmTransactionReject(uint transactionId)
public
{
require(isOwner[msg.sender]);
require(transactions[transactionId].destination != address(0));
require(confirmations[transactionId][msg.sender] == false);
confirmations[transactionId][msg.sender] = true;
// Transaction.testing[msg.sender] = true;
acceptance[transactionId][msg.sender] = false;
emit Confirmation(msg.sender, transactionId);
executeTransaction(transactionId);
}

/// @dev Allows an owner to revoke a confirmation for a transaction.
/// @param transactionId Transaction ID.
function revokeConfirmation(uint transactionId) public {}

/// @dev Allows anyone to execute a confirmed transaction.
/// @param transactionId Transaction ID.
function executeTransaction(uint transactionId)
    public
{
    require(transactions[transactionId].executed == false);
    if (isConfirmed(transactionId)) {
        uint flag=0;
        for(uint i=0;i<required;i++)
        {
            if(acceptance[transactionId][owners[i]] == false)
                flag=1;
        }           

        Transaction storage t = transactions[transactionId];
        if(flag==0)
            t.accepted = true;
        t.executed = true;

        (bool success,) = t.destination.call{value:(t.value)}("");
        if (success)    
            emit Execution(transactionId);
        else {
            emit ExecutionFailure(transactionId);
            t.executed = false;
        }
    }
}
    /*
     * (Possible) Helper Functions
     */
/// @dev Returns the confirmation status of a transaction.
/// @param transactionId Transaction ID.
/// @return Confirmation status.
function isConfirmed(uint transactionId)
    public
    view
    returns (bool)
{
    uint count = 0;
    for (uint i=0; i<owners.length; i++) {
        if (confirmations[transactionId][owners[i]])
            count += 1;
        if (count == required)
            return true;
    }
}

// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
// @param destination Transaction target address.
// @param value Transaction ether value.
// @param data Transaction data payload.
// @return Returns transaction ID.
function addTransaction(address destination, uint value)
    internal
    returns (uint transactionId)
{
    transactionId = transactionCount;
    transactions[transactionId] = Transaction({
        destination: destination,
        value: value,
        executed: false,
        accepted:false
    });
    transactionCount += 1;
    emit Submission(transactionId);
}
Enter fullscreen mode Exit fullscreen mode

}`

Discussion (1)

Collapse
hasha_netha profile image
Harshavardhan Gurram Author

I'm using Injected web3 with metamask.