hypha-dao / dho-web-client

The DHO (Decentralized Human Organization) is a framework to build your organization from the ground up in an organic and participative way and together with others.
https://dao.hypha.earth/
Apache License 2.0
13 stars 8 forks source link

Multisig Approval transition/enablement #79

Closed mgravitt closed 2 years ago

mgravitt commented 4 years ago

I've deployed a multisig contract to msig.hypha. We should have a form in the UI (admin section, perhaps?) where approvers can approve multisig transactions.

Transactions will always be created via the CLI, but approval via the UI is super helpful.

I'll use this issue to document how to interact with the contract.

gregory-latinier commented 4 years ago

I've never done multisig so I don't know what the user needs. Could you be more specific on the UI ? What fields are needed, their purpose ? What action has to be called ? Should this feature be limited to some users / roles ?

Thanks

mgravitt commented 4 years ago

@gregory-latinier @sceenius In order to test the multi-signature form, we need to create individual accounts for us on the test network. From within Anchor, can you go to "Tools -> Manage Keys -> Generate Key Pairs". This will create some keys and you can save them to the your wallet.

Copy one of the public keys and send it to me. I will create an account for you on the testnet. I will create "g.hypha" and "j.hypha", and then I will add these accounts to a few accounts so we can approve new deployments on testnet via this new screen.

sceenius commented 4 years ago

@dappdever My public key: EOS6UG1hEqtmyX4iDFBoB7yeWjxh2FWLq1r5dYF7kmMvMpQVzPLSa

gregory-latinier commented 4 years ago

EOS8QsiSuoW6sofc5yDsbZMUXgjrzUDkTcTo2op8y4DG6Ucm2sQwS

mgravitt commented 4 years ago

Here's how to retrieve the list of multisig proposals (proposal table):

cleos -u https://test.telos.kitchen get table msig.hypha msig.hypha proposal                       
{
  "rows": [{
      "proposal_name": "mytestdeploy",
      "proposer": "m.hypha",
      "packed_transaction": "6ce16c5f74e9c4b244a500000000020000000000ea305500000040258ab2c201008069d53790b1ca00000000a8ed32328809008069d53790b1ca0000fc080061736d0100000001370b60027f7f0060017e0060017f006000017f60037f7f7f017f60027f7f017f60027f7e0060000060037e7e7e0060017f017f60027e7e00029d010903656e76087072696e74735f6c000003656e76067072696e746e000103656e76067072696e7473000203656e7610616374696f6e5f646174615f73697a65000303656e760c656f73696f5f617373657274000003656e76066d656d736574000403656e7610726561645f616374696f6e5f64617461000503656e76066d656d637079000403656e7611656f73696f5f6173736572745f636f6465000603080707080907020a0a0405017001010105030100010616037f014180c0000b7f0041bfc0000b7f0041bfc0000b070901056170706c79000a0a8f06070400100c0b9101001009200020015104404280808080808080c0eb00200251044020002001100e054280808080808080ca3f200251044020002001100f052000428080808080c0ba98d500520440410042808080d9d3b3ed82ef0010080b0b0b05428080808080c0ba98d50020015104404280808080aefadeeaa47f2002510440410042818080d9d3b3ed82ef0010080b0b0b4100100d0b800101037f02400240024002402000450d004100410028028c40200041107622016a220236028c404100410028028440220320006a41076a417871220036028440200241107420004d0d0120014000417f460d020c030b41000f0b4100200241016a36028c40200141016a4000417f470d010b41004190c000100420030f0b20030b3601017f230041106b2200410036020c4100200028020c28020041076a417871220036028440410020003602804041003f0036028c400b02000bdb0102047f017e230041106b22022103200224000240024002400240024010032204450d002004418004490d012004100b21020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410061a20034200370308200341086a2105200441074b0d010b410041bac00010040b20052002410810071a41a9c000210420032903082106024041a9c0002d00002202450d000240034020024125460d01200441011000200441016a22042d00002202450d020c000b0b20061001200441016a10020b200341106a24000bdb0102047f017e230041106b22022103200224000240024002400240024010032204450d002004418004490d012004100b21020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410061a20034200370308200341086a2105200441074b0d010b410041bac00010040b20052002410810071a41b1c000210420032903082106024041b1c0002d00002202450d000240034020024125460d01200441011000200441016a22042d00002202450d020c000b0b20061001200441016a10020b200341106a24000b0b4e04004190c0000b216661696c656420746f20616c6c6f63617465207061676573006869203a20250a000041b1c0000b09627965203a20250a000041bac0000b0572656164000041000b04402000000000000000ea305500000000b863b2c201008069d53790b1ca00000000a8ed32327b008069d53790b1ca720e656f73696f3a3a6162692f312e310002036279650001026e6d046e616d650268690001026e6d046e616d6502000000000000943f0362796500000000000000806b026869275374756220666f7220686920616374696f6e27732072696361726469616e20636f6e7472616374000000000000",
      "requested_approvals": [{
          "level": {
            "actor": "g.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "j.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "m.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "n.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        }
      ],
      "provided_approvals": [],
      "document_hash": "1110a04052c2e6c5ca566b33ced442256d0730f6de29184ec0a7f27e02a5b0eb"
    }
  ],
  "more": false,
  "next_key": ""
}

NOTE that the requested approvals is an array of accounts. When these accounts approve the proposal, the account will show in the provided_approvals array and be removed from the requested_approvals.

mgravitt commented 4 years ago

The document_hash on the proposal object links to a document, which can be retrieved like this:

cleos -u https://test.telos.kitchen get table -l 1 --index 2 --key-type sha256 -L 1110a04052c2e6c5ca566b33ced442256d0730f6de29184ec0a7f27e02a5b0eb msig.hypha msig.hypha documents
{
  "rows": [{
      "id": 0,
      "hash": "1110a04052c2e6c5ca566b33ced442256d0730f6de29184ec0a7f27e02a5b0eb",
      "creator": "m.hypha",
      "content_groups": [[{
            "label": "content_group_name",
            "value": [
              "string",
              "Deployment Proposal Details"
            ]
          },{
            "label": "github_commit",
            "value": [
              "string",
              "https://github.com/hypha-dao/test/commit/28e0a4bb8b03416727acb34c5ba61ed34bc0e42b"
            ]
          },{
            "label": "notes",
            "value": [
              "string",
              "This smart contract update adds the bye action back, simply as a test"
            ]
          },{
            "label": "developer",
            "value": [
              "name",
              "hyphanewyork"
            ]
          },{
            "label": "approved_policy_document",
            "value": [
              "checksum256",
              "7b5755ce318c42fc750a754b4734282d1fad08e52c0de04762cb5f159a253c24"
            ]
          }
        ]
      ],
      "certificates": [],
      "created_date": "2020-09-22T20:23:38.500"
    }
  ],
  "more": false,
  "next_key": ""
}
mgravitt commented 4 years ago

Here are some specs on the multisig screen:

View requirements

Action requirements:

gregory-latinier commented 4 years ago

Should the screen view restricted to specific users ? If yes based on which criteria ? The execute button should be visible by who ?

I will develop a table like the treasury screen

mgravitt commented 4 years ago

@gregory-latinier - for now, all users can see this. Any accounts that are listed in provided_approvals should be able to see/access the execute button.

sceenius commented 4 years ago

From the UI pov it looks good to me (assuming the table move down a bit as on testing). If there is an action button, please add ACTION to the last column. Let's use text buttons for this.

sceenius commented 4 years ago

@dappdever @gregory-latinier Can we call this view "Multisignature" instead of Treasury so we don't get confused with the redemption process? Otherwise looks good on my end. I can't really test this further.

gregory-latinier commented 4 years ago

@sceenius I don't understand the multisignature page is not the same than the Treasury page I can rename Multi Sig to Multisignature but Treasury to Multisignature doesn't make sense

sceenius commented 4 years ago

@gregory-latinier Yes, let's call this Multi Sig - image

mgravitt commented 4 years ago

Changing this Github issue to document the steps for going multisignature in production.

  1. Create new accounts on mainnet with the following keys: (@dappdever)
  1. Update dao.hypha permissions using the following command, (@dappdever )
eosc -u https://api.telos.kitchen --vault-file ../daoctl/dao.hypha.json tx create eosio updateauth '{
    "account": "dao.hypha",
    "permission": "active",
    "parent": "owner",
    "auth": {
        "keys":[
            {
                "key": "EOS5Y5MwfVEDUzRBJVBoWepYK3DBeQ75E8xnhAUjMv6JDuQCJ69UC",
                "weight": 2
            }
        ],
        "threshold": 2,
        "accounts": [
              {
                "permission": {
                    "actor": "dao.hypha",
                    "permission": "eosio.code"
                },
                "weight": 2
            },
            {
                "permission": {
                    "actor": "g.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
            {
                "permission": {
                    "actor": "j.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
            {
                "permission": {
                    "actor": "m.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
           {
                "permission": {
                    "actor": "msig.hypha",
                    "permission": "active"
                },
                "weight": 2
            },
             {
                "permission": {
                    "actor": "n.hypha",
                    "permission": "active"
                },
                "weight": 1
            }
        ],
        "waits": []
    }
}' -p dao.hypha@owner
  1. Create an msig proposal to test out the new permissions. (@dappdever )
cleos -u https://api.telos.kitchen push transaction eosio.token transfer '["dao.hypha", "trailservice", "10.0000 TLOS", "deposit"]' -sjd -x 186400 -p dao.hypha > simple_transfer.json

Edit simple_transfer.json to add the additional content:

cleos -u https://api.telos.kitchen push action msig.hypha propose '{
  "proposer": "m.hypha",
  "proposal_name": "simplexfer",
  "requested": [
     {
      "actor": "g.hypha",
      "permission": "active"
    },
     {
      "actor": "j.hypha",
      "permission": "active"
    },
     {
      "actor": "m.hypha",
      "permission": "active"
    },
    {
      "actor": "n.hypha",
      "permission": "active"
    }
  ],
  "content_groups": [
    [
      {
        "label": "content_group_name",
        "value": [
          "string",
          "Proposal Details"
        ]
      },
      {
        "label": "notes",
        "value": [
          "string",
          "Transferring 10 TLOS to telos decide"
        ]
      }
    ]
  ],
  "trx": {
    "expiration": "2020-09-30T18:46:55",
    "ref_block_num": 40425,
    "ref_block_prefix": 1566149855,
    "max_net_usage_words": 0,
    "max_cpu_usage_ms": 0,
    "delay_sec": 0,
    "context_free_actions": [],
    "actions": [{
        "account": "eosio.token",
        "name": "transfer",
        "authorization": [{
            "actor": "dao.hypha",
            "permission": "active"
            }
        ],
        "data": "000030adfa06a849a090db57e1e8cccda08601000000000004544c4f53000000076465706f736974"
        }
    ],
    "transaction_extensions": [],
    "signatures": [],
    "context_free_data": []
    }
}' -p m.hypha
  1. Now, this transfer will show in the table on the multisignature page. Two of @gregory-latinier, @sceenius or Nik will approve and execute and then we'll confirm that the transfer occurred.

  2. If that works, update permissions to remove the key.

    cleos -u https://test.telos.kitchen push action eosio updateauth '{
    "account": "dao.hypha",
    "permission": "active",
    "parent": "owner",
    "auth": {
        "keys":[],
        "threshold": 2,
        "accounts": [
              {
                "permission": {
                    "actor": "dao.hypha",
                    "permission": "eosio.code"
                },
                "weight": 2
            },
            {
                "permission": {
                    "actor": "g.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
            {
                "permission": {
                    "actor": "j.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
            {
                "permission": {
                    "actor": "m.hypha",
                    "permission": "active"
                },
                "weight": 1
            },
            {
                "permission": {
                    "actor": "msig.hypha",
                    "permission": "active"
                },
                "weight": 2
            },
             {
                "permission": {
                    "actor": "n.hypha",
                    "permission": "active"
                },
                "weight": 1
            }
        ],
        "waits": []
    }
    }' -p dao.hypha@owner
mgravitt commented 3 years ago

Command to update msig.hypha permissions:

eosc -u https://api.telos.kitchen --vault-file ../daoctl/dao.hypha.json tx create eosio updateauth '{
    "account": "msig.hypha",
    "permission": "active",
    "parent": "owner",
    "auth": {
        "keys":[
            {
                "key": "EOS5Y5MwfVEDUzRBJVBoWepYK3DBeQ75E8xnhAUjMv6JDuQCJ69UC",
                "weight": 1
            }
        ],
        "threshold": 1,
        "accounts": [
              {
                "permission": {
                    "actor": "msig.hypha",
                    "permission": "eosio.code"
                },
                "weight": 1
            }
        ],
        "waits": []
    }
}' -p msig.hypha@owner
mgravitt commented 3 years ago

We've confirmed that we cannot do this in our own contract because the transaction needs to be signed by the eosio account because that account is not subject to the inline action too big check.

In the current design, the transaction and the document are submitted to the msig.hypha contract.

Instead, we need to split this into two actions. The document content can still be submitted to msig.hypha (in fact, we can just submit it to dao.hypha if it is easier, but it would need to be an action separate from proposals because it is not voted on by members). The actual transaction with the setcode and setabi action need to be submitted to eosio.msig. The parameters are exactly the same, except remove the []ContentGroup parameter.

Step 1. The deployment struct needs to be changed to remove the []ContentGroup, and it can be moved to a separate struct.

Here: https://github.com/hypha-dao/daoctl/blob/develop/cmd/proposeDeployment.go#L9

Step 2. Change the msig.hypha::propose action to only include the []ContentGroups, and simply store the document. Also, ensure that their is an erasedoc action that will be called in the transaction that will ultimately execute the multisig deployment. (You don't have to worry about this yet- this is really only needed when we integrate the UI.)

Step 3. The action constructed at the line below needs to be split into two action calls (can still be the same transaction).

https://github.com/hypha-dao/daoctl/blob/9e802b8d9ff58a6570d304f00840655cf9d04523/cmd/proposeDeploymentCreate.go#L229

Step 4. Testing. Once the transaction is submitted to eosio.msig, any one of the users (m.hypha, gh.hypha, jj.hypha, l.hypha, etc) can approve the deployment by invoking eosio.msig::approve. Once enough people have signed, the transaction can be executed using the eosio.msig::exec action, which upgrades the contract.

mgravitt commented 3 years ago

The multisig page should be updated now with some relatively small changes. Currently, I think it queries only from msig.hypha, but it should query some data from msig.hypha and some data from eosio.msig.

Also, the approve and exec action calls need to be updated to be called on eosio.msig.

The list of proposals should come from the proposals table, whereas I believe the code is currently querying from the proposal table.

image

This will retrieve the list of proposals:

❯ cleos -u https://test.telos.kitchen get table msig.hypha msig.hypha proposals{
  "rows": [{
      "proposer": "m.hypha",
      "proposal_name": "testprop",
      "document_hash": "99fb1fb99421d8e1f3b5320af264849408f481dbe4347e0f63a94e983d779e3e"
    }
  ],
  "more": false,
  "next_key": ""
}

The requested_approvals and provided_approvals can then be queried from the eosio.msig contract, like so:

❯ cleos -u https://test.telos.kitchen get table -L testprop -U testprop eosio.msig m.hypha approvals2
{
  "rows": [{
      "version": 1,
      "proposal_name": "testprop",
      "requested_approvals": [{
          "level": {
            "actor": "gh.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "m.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "j.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "jj.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        },{
          "level": {
            "actor": "l.hypha",
            "permission": "active"
          },
          "time": "1970-01-01T00:00:00.000"
        }
      ],
      "provided_approvals": []
    }
  ],
  "more": false,
  "next_key": ""
}

The format should be the same as what is currently happening, except approval data is queried from eosio.msig instead of msig.hypha.

Lastly, the document data includes developer, notes, and github link. This should be queried from msig.hypha (not DGraph). I believe that the existing code should already be doing this correctly.