[Ethereum] How to get contract public values with nethereum as the wallet does

go-ethereumnethereum

I'm fiddling around with this tutorial.

After deploying and setting up the contract within the page, I created a proposal from the ethereum wallet which I could see after a few blocks. The read from contracts part shows all proposals, available by their number. This implies that the proposals are available readily somewhere but I want to know how to geth them via nethereum.

I have the contract ready as below.

contract = web3.Eth.GetContract(abi, contractAddress);

enter image description here

How can I get the data?

Best Answer

The Nethereum.Web.Sample shows you how to interact with the DAO.

Dao in Nethereum

In the sample there is a generic DAO service Source code in Github

A simple pattern to create a contract service, is to instantiate it with your Web3 class and ABI.

public class DaoService
{
    private readonly Web3.Web3 web3;
    private string abi = @"abi...";
    private Contract contract;
    public DaoService(Web3.Web3 web3, string address)
    {
        this.web3 = web3;
        this.contract = web3.Eth.GetContract(abi, address);
    }

The DAO stores the total number of proposals by declaring a public attribute, this can be accessed as follows:

    public Task<long> GetNumberOfProposals()
    {
        return contract.GetFunction("numberOfProposals").CallAsync<long>();
    }

If you want to retrieve all the Proposals you can iterate from 0 to the total number of proposals and add them to a collection as:

    public async Task<List<Proposal>> GetAllProposals()
    {

        var numberOfProposals = await GetNumberOfProposals().ConfigureAwait(false);
        var proposals = new List<Proposal>();

        for (var i = 0; i < numberOfProposals; i++)
        {
            proposals.Add(await GetProposal(i).ConfigureAwait(false));
        }
        return proposals;
    }

What is missing above is how to get that specific Proposal data to so you can call the function "proposals" this is in solidity the "mapping" of the proposal number and the struct proposal, which are output parameters.

   public async Task<Proposal> GetProposal(long index)
    {
        var proposalsFunction = contract.GetFunction("proposals");
        var proposal = await proposalsFunction.CallDeserializingToObjectAsync<Proposal>(index).ConfigureAwait(false);
        proposal.Index = index;
        return proposal;
    }

Above you may have noticed the output is deserialised into a Proposal Object, this is the FunctionOuput and requires information (from the ABI) to do the deserialisation.

[FunctionOutput]
public class Proposal
{
    public long Index { get; set; }

    [Parameter("address", 1)]
    public string Recipient { get; set; }

    [Parameter("uint256", 2)]
    public BigInteger Amount { get; set; }

    [Parameter("string", 3)]
    public string Description { get; set; }

    [Parameter("uint256", 4)]
    public BigInteger VotingDeadline { get; set; }

    [Parameter("bool", 5)]
    public bool Open { get; set; }

    [Parameter("bool", 6)]
    public bool ProposalPassed { get; set; }

    [Parameter("bytes32", 7)]
    public byte[] ProposalHash { get; set; }

    public string GetProposalHashToHex()
    {
        return ProposalHash.ToHex();
    }

    [Parameter("uint256", 8)]
    public BigInteger ProposalDeposit { get; set; }

    [Parameter("bool", 9)]
    public bool NewCurator { get; set; }

    [Parameter("uint256", 10)]
    public BigInteger Yea { get; set; }

    [Parameter("uint256", 11)]
    public BigInteger Nay { get; set; }

    [Parameter("address", 12)]
    public string Creator { get; set; }
}
Related Topic