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.


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?

  • Not sure if I'm getting this properly, but why isn't one contract with hashes enough, and both parties call a function that checks for a possibly hardcoded contract address (or it can be set via another function) using msg.sender, and if both have 'signed off' by changing a state variable do whatever you must do?
    – Joël
    Commented Jul 16, 2017 at 16:40
  • I'm voting to keep this open because it has upvotes and an accepted answer. I don't think it's too broad. He's just generalizing a reasonable question about how to approach a certain set of problems. Commented Jul 17, 2017 at 23:15
  • @Joël I'm not sure I understand. Can you please clarify your idea by giving an example? Commented Jul 19, 2017 at 8:50
  • I think Rob's solution is along the same lines.
    – Joël
    Commented Jul 19, 2017 at 8:58

2 Answers 2


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;


There are many ways to do so . let us take one method :-
Make a Double Mapping such that two contractor address pass the same key and map with this key. If invalid then kill the contract or throw the message in User interface .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.