Solidity, Contract Development, Contract Design, Consensus – Executing a Smart Contract with Both Parties’ Agreement

consensuscontract-designcontract-developmentsolidity

I am writing a Solidity contract which publishes documents (or, more precisely, stores the documents' hashes) on the Ethereum blockchain. Currently, I have no idea how to write the code so that the contract only executes after both the 2 involved parties have agreed on the document's content.

Digital signature is one solution I have thought of. However, my intent is to not let any single party to publish the document after they have modified its content as they want.

UPDATE / EDIT

Maybe I was complicating the problem. Just store a list of documents (actually their hashes) agreed by one party and another list of documents agreed by both. Each party runs the contract from their address. It only executes if the calling address is of an involved party which has not agreed.

The verification process only needs to deal with the second list.

What is the possible solution to this?

Best Answer

Here's a really minimal example that keeps two lists. When both parties approve the same hash, the document hash (id) is copied to the approved list.

Just a sketch to possibly give you some ideas. Seems to work. No warranty.

pragma solidity ^0.4.6;

contract TwoSigs {

    address public partyA;
    address public partyB;

    struct documentStruct {
        bool approvedByA;
        bool approvedByB;
    }

    // this data is all publicly explorable

    mapping(bytes32 => documentStruct) public documentStructs;
    bytes32[] public documentList; // all
    bytes32[] public approvedDocuments; // approved

    // for event listeners    

    event LogProposedDocument(address proposer, bytes32 docHash);
    event LogApprovedDocument(address approver, bytes32 docHash);

    // constructor needs to know who A & B are

    function TwoSigs(address addressA, address addressB) {
        partyA = addressA;
        partyB = addressB;
    }

    // for convenient iteration over both lists
    function getDocumentsCount() public constant returns(uint docCount) {
        return documentList.length;
    }

    function getApprovedCount() public constant returns(uint apprCount) {
        return approvedDocuments.length;
    }

    // propose / Approve

    function agreeDoc(bytes32 hash) public returns(bool success) {
        if(msg.sender != partyA && msg.sender != partyB) throw; // stranger. abort. 
        if(msg.sender == partyA) documentStructs[hash].approvedByA = true; // could do else. it's A or B.
        if(msg.sender == partyB) documentStructs[hash].approvedByB = true; 

        if(documentStructs[hash].approvedByA == true && documentStructs[hash].approvedByB == true) {
            uint docCount = documentList.push(hash);
            LogApprovedDocument(msg.sender, hash);
        } else {
            uint apprCount = approvedDocuments.push(hash);
            LogProposedDocument(msg.sender, hash);
        }
        return true;
    }

}
Related Topic