Создание и Использование Multisig КонтрактаСоздание и Использование Multisig Контракта

Создание и Использование

Генерация Кода Специального Multisig Контракта

Перед тем как продолжить убедитесь в том, что Вы выполнили все шаги в Настройках.

Чтобы увидеть список поддерживаемых контрактов и действий, введите следующую команду:

stack exec — lorentz-contract-multisig —help

Вы также можете использовать инструмент lorentz-contract-multisig для генерации кода Michelson для контракта Multisig, который Вы желаете создать, с функцией приема только одного параметра, выбранного Вами.

Предположим, мы хотим сгенерировать multisig контракт, который принимает исключительно nat как допустимый аргумент. Это возможно сделать используя следующую специальную команду:

$ stack exec — lorentz-contract-multisig GenericMultisig print-specialized —parameterType ‘nat’ —oneline

 

parameter (or (unit %default) (pair %mainParameter (pair nat (or (pair nat (contract nat)) (pair nat (list key)))) (list (option signature))));storage (pair nat (pair nat (list key)));code { CAST (pair (or unit (pair (pair nat (or (pair nat (contract nat)) (pair nat (list key)))) (list (option signature)))) (pair nat (pair nat (list key))));DUP;CAR;DIP { CDR };IF_LEFT { DROP;NIL operation;PAIR }        { PUSH mutez 0;AMOUNT;COMPARE;EQ;IF {  }   { PUSH string «Some tokens were sent to this contract outside of the default entry point.»;FAILWITH };SWAP;DUP;DIP { SWAP };DIP { DUP;CAR;DIP { CDR };DUP;SELF;ADDRESS;PAIR;PACK;DIP { DUP;CAR;DIP { CDR };DIP { SWAP } };SWAP };DUP;CAR;DIP { CDR };DIP { SWAP };COMPARE;EQ;IF {  }   { PUSH string «Counters do not match.»;FAILWITH };DIP { SWAP };DUP;CAR;DIP { CDR };DIP { PUSH nat 0;SWAP;ITER { DIP { SWAP };SWAP;IF_CONS { IF_NONE { SWAP;DROP }        { SWAP;DIP { SWAP;DIP { DIP { DIP { DUP };SWAP } };DIP 2 { DUP };DIG 2;DIP { CHECK_SIGNATURE };SWAP;IF { DROP }   { FAILWITH };PUSH nat 1;ADD } } }        { FAILWITH };SWAP } };COMPARE;LE;IF {  }   { PUSH string «Quorum not present»;FAILWITH };IF_CONS { FAILWITH }        {  };DROP;DIP { DUP;CAR;DIP { CDR };PUSH nat 1;ADD;PAIR };IF_LEFT { SWAP;DIP { DUP;CAR;DIP { CDR };DIP { DIP { NIL operation };PUSH mutez 0 };TRANSFER_TOKENS;CONS };SWAP }        { DIP { CAR };SWAP;PAIR;NIL operation };PAIR } };

Скрипт lorentz-contract-multisig позволил нам сгенерировать контракт Michelson. Этот же скрипт можем применять для всевозможных типов Michelson.

Если мы генерируем контракт используя map из string в int, в таком случае команда будет выглядеть следующим образом:

$ stack exec — lorentz-contract-multisig GenericMultisig print-specialized —parameterType ‘map string int’ —oneline

 

parameter (or (unit %default) (pair %mainParameter (pair nat (or (pair (map string int) (contract (map string int))) (pair nat (list key)))) (list (option signature))));storage (pair nat (pair nat (list key)));code { CAST (pair (or unit (pair (pair nat (or (pair (map string int) (contract (map string int))) (pair nat (list key)))) (list (option signature)))) (pair nat (pair nat (list key))));DUP;CAR;DIP { CDR };IF_LEFT { DROP;NIL operation;PAIR }        { PUSH mutez 0;AMOUNT;COMPARE;EQ;IF {  }   { PUSH string «Some tokens were sent to this contract outside of the default entry point.»;FAILWITH };SWAP;DUP;DIP { SWAP };DIP { DUP;CAR;DIP { CDR };DUP;SELF;ADDRESS;PAIR;PACK;DIP { DUP;CAR;DIP { CDR };DIP { SWAP } };SWAP };DUP;CAR;DIP { CDR };DIP { SWAP };COMPARE;EQ;IF {  }   { PUSH string «Counters do not match.»;FAILWITH };DIP { SWAP };DUP;CAR;DIP { CDR };DIP { PUSH nat 0;SWAP;ITER { DIP { SWAP };SWAP;IF_CONS { IF_NONE { SWAP;DROP }        { SWAP;DIP { SWAP;DIP { DIP { DIP { DUP };SWAP } };DIP 2 { DUP };DIG 2;DIP { CHECK_SIGNATURE };SWAP;IF { DROP }   { FAILWITH };PUSH nat 1;ADD } } }        { FAILWITH };SWAP } };COMPARE;LE;IF {  }   { PUSH string «Quorum not present»;FAILWITH };IF_CONS { FAILWITH }        {  };DROP;DIP { DUP;CAR;DIP { CDR };PUSH nat 1;ADD;PAIR };IF_LEFT { SWAP;DIP { DUP;CAR;DIP { CDR };DIP { DIP { NIL operation };PUSH mutez 0 };TRANSFER_TOKENS;CONS };SWAP }        { DIP { CAR };SWAP;PAIR;NIL operation };PAIR } };

Вы можете сравнить два выхода представленных выше и увидеть, куда был вставлен новый тип.

При попытке сгенерировать контракт используя неподдерживаемый тип, получим ошибку парсинга. Инструмент lorentz-contract-multisig выполняет проверку соответствия типов за Вас.

$ stack exec — lorentz-contract-multisig GenericMultisig print-specialized —parameterType ‘not-a-type’ —oneline

 

ParseErrorBundle {bundleErrors = FancyError 0 (fromList [ErrorCustom UnknownTypeException]) 😐 [], bundlePosState = PosState {pstateInput = «not-a-type», pstateOffset = 0, pstateSourcePos = SourcePos {sourceName = «parameter», sourceLine = Pos 1, sourceColumn = Pos 1}, pstateTabWidth = Pos 8, pstateLinePrefix = «»}}

CallStack (from HasCallStack):

  error, called at src/Lorentz/Contracts/GenericMultisig/Parsers.hs:285:29 in lorentz-contract-multisig-0.1.0.0-53SsL7tj942CZsUdhk5Z7N:Lorentz.Contracts.GenericMultisig.Parsers

Генерация Исходной системы хранения (исходного хранилища) 

Обратите внимание: данная секция использует следующие bash функции 

Универсальный Multisig позволяет присваивать администраторов контракту (signerKeys), а также определенное количество администраторов, необходимое для подписания. CLI инструмент позволяет быть администраторами только аккаунтам tz1, однако контракт допускает использование KT1 аккаунтов.

Для создания контракта Michelson для Исходной системы хранения, например для двух администраторов, используйте следующие команды:

$ stack exec — lorentz-contract-multisig GenericMultisig init-specialized \

  —threshold 1 —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»

 

Pair 0 (Pair 1 { «edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qb»; «edpkvCHgVArnZo9RTP4P6euLTyhE89u73CYjBgsP4wEJbj4quao9oR» })

Важно отметить, что для правильного парсинга списка signerKeys, необходимо отделить кавычки и разделить их запятой без пробела.

В команде представленной выше, мы добавили два возможных администратора, которые могут выполнять подпись, и установили пороговое значение threshold 1. Если мы инициализируем multisig контракт с этим хранилищем, все транзакции в нем должны быть подписаны хотя бы одним из двух администраторов в списке, для того чтобы транзакции были действительными.

Если пороговое значение установлено выше, чем число администраторов, которые могут выполнить подпись, в таком случае будет выдаваться ошибка, так как невозможно иметь больше администраторов для подписи, чем указано в списке signerKeys:

$ stack exec — lorentz-contract-multisig GenericMultisig init-specialized —threshold 2 —signerKeys «[\»$(get_public_key bob)\»]»

 

threshold is greater than the number of signer keys

CallStack (from HasCallStack):

  error, called at src/Lorentz/Contracts/GenericMultisig/CmdLnArgs.hs:246:13 in lorentz-contract-multisig-0.1.0.0-53SsL7tj942CZsUdhk5Z7N:Lorentz.Contracts.GenericMultisig.CmdLnArgs

 

Создание Multisig Контракта Со Сгенерированным Michelson

Используя команды, которые мы применили выше, можно создать контракт при помощи tezos-client, нашего контракта и сгенерированного хранилища. Создадим контракт MultisigNat двумя администраторами — Bob и Alice, который позволит использовать параметры типа nat.

$ tezos-client —wait none originate contract MultisigNat transferring 0 from $BOB_ADDRESS running «$(stack exec — lorentz-contract-multisig GenericMultisig print-specialized —parameterType ‘nat’ —oneline)»    —init «$(stack exec — lorentz-contract-multisig GenericMultisig init-specialized —threshold 1 —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»)» —burn-cap 1.13

 

Waiting for the node to be bootstrapped before injection…

Current head: BL7oqTukMZqp (timestamp: 2020-04-10T17:48:51-00:00, validation: 2020-04-10T17:48:54-00:00)

Node is bootstrapped, ready for injecting operations.

Estimated gas: 31869 units (will add 100 for safety)

Estimated storage: 1130 bytes added (will add 20 for safety)

Operation successfully injected in the node.

Operation hash is ‘ooEyZR49BY3t9wxXJekem5No3PxaixCvsVY9UAm3FxJfHDUaxYS’

NOT waiting for the operation to be included.

Use command

  tezos-client wait for ooEyZR49BY3t9wxXJekem5No3PxaixCvsVY9UAm3FxJfHDUaxYS to be included —confirmations 30 —branch BL7oqTukMZqpBxoDK83aQgo1bCcbqYu7sWVQRHv5kws2EpyxGm9

and/or an external block explorer to make sure that it has been included.

This sequence of operations was run:

  Manager signed operations:

    From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

    Fee to the baker: ꜩ0.004342

    Expected counter: 623944

    Gas limit: 31969

    Storage limit: 1150 bytes

    Balance updates:

      tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm …………. -ꜩ0.004342

      fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,163) … +ꜩ0.004342

    Origination:

      From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

      Credit: ꜩ0

      Script:

        { … }

        Initial storage:

          (Pair 0

                (Pair 1

                      { «edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qb» ;

                        «edpkvCHgVArnZo9RTP4P6euLTyhE89u73CYjBgsP4wEJbj4quao9oR» }))

        No delegate for this contract

        This origination was successfully applied

        Originated contracts:

          KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC

        Storage size: 873 bytes

        Paid storage size diff: 873 bytes

        Consumed gas: 31869

        Balance updates:

          tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm … -ꜩ0.873

          tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm … -ꜩ0.257

 

New contract KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC originated.

Contract memorized as MultisigNat.

Теперь мы можем извлечь адрес контракта и сохранить его в переменной bash.

$ MULTISIG_NAT_ADDRESS=»KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC»

Администрирование Второго Контракта Со Специализированным Multisig

Создание Контракта Admin42

Теперь контракт MultisigNat может быть использован для администрирования контрактов, которые используют параметр типа nat. В этом обучающем материале мы будем использовать пример контракта, который может быть найден в репозитории lorentz-contract-multisig repository, и называется Admin42. Данный контракт требует наличия администратора для взаимодействия с ним, и принимает параметр типа nat (только параметр 42, если быть точными!), и теперь можно использовать наш MultisigNat для его администрирования.

(Больше информации о контракте Admin42 Вы можете найти по ссылке: lorentz-contract-multisig repo)

В первую очередь мы создадим контракт Admin42, сделав наш MultisigNat администратором. 

$ tezos-client —wait none originate contract MultisigAdmin42 transferring 0 from $BOB_ADDRESS running «$(cat admin_42.tz | tr ‘\n’ ‘ ‘)» —init «\»$MULTISIG_NAT_ADDRESS\»» —burn-cap 0.406

 

Waiting for the node to be bootstrapped before injection…

Current head: BKpKZvm6k3wJ (timestamp: 2020-04-10T17:50:57-00:00, validation: 2020-04-10T17:51:42-00:00)

Node is bootstrapped, ready for injecting operations.

Estimated gas: 13516 units (will add 100 for safety)

Estimated storage: 406 bytes added (will add 20 for safety)

Operation successfully injected in the node.

Operation hash is ‘ookjPrjibe9g7Gjz6KU9FzUrAu7kwKqWd3weqeHuMnysdoLop7z’

NOT waiting for the operation to be included.

Use command

  tezos-client wait for ookjPrjibe9g7Gjz6KU9FzUrAu7kwKqWd3weqeHuMnysdoLop7z to be included —confirmations 30 —branch BKpKZvm6k3wJ5bBxiNVpExCvMReWJ3GzBCiia1u5xcoV2mHyPpz

and/or an external block explorer to make sure that it has been included.

This sequence of operations was run:

  Manager signed operations:

    From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

    Fee to the baker: ꜩ0.001754

    Expected counter: 623945

    Gas limit: 13616

    Storage limit: 426 bytes

    Balance updates:

      tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm …………. -ꜩ0.001754

      fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,163) … +ꜩ0.001754

    Origination:

      From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

      Credit: ꜩ0

      Script:

        { parameter nat ;

          storage address ;

          code { DUP ;

                 CDR ;

                 SENDER ;

                 ASSERT_CMPEQ ;

                 DUP ;

                 CAR ;

                 PUSH nat 42 ;

                 ASSERT_CMPEQ ;

                 CDR ;

                 NIL operation ;

                 PAIR } }

        Initial storage: «KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC»

        No delegate for this contract

        This origination was successfully applied

        Originated contracts:

          KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj

        Storage size: 149 bytes

        Paid storage size diff: 149 bytes

        Consumed gas: 13516

        Balance updates:

          tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm … -ꜩ0.149

          tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm … -ꜩ0.257

 

New contract KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj originated.

Contract memorized as MultisigAdmin42.

Теперь сохраните адрес контракта в переменной:

MULTISIG_ADMIN42_ADDRESS=»KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj»

 

Подписание Транзакции С Одним Администратором

При взаимодействии с нашим контрактом MultisigNat, необходимо иметь достаточное количество админ-ключей для того, чтобы соответствовать пороговому значению. В данном случае, есть два администратора и пороговое значение threshold 1, следовательно, Bob или Alice должны подписать любую транзакцию, которая предусматривается этим контрактом, в ином случае транзакция будет отклонена.

Шаги для подписания транзакции:

  1. Сгенерировать байты
  2. Подписать байты
  3. Сохранить подпись
  4. Инициировать (Запустить) транзакцию используя подпись

Попробуем для начала подписать операцию именем Alice. В первую очередь мы сгенерируем байты для подписи, используя инструмент lorentz-contract-multisig.

$ stack exec — lorentz-contract-multisig GenericMultisig run-multisig —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»»    —multisig-contract «$MULTISIG_NAT_ADDRESS»    —counter 0      —signatures «Nothing»     —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»

 

«0x0507070a0000001601a74b12a982f45edfaa7f13b03a65ab6fab90bf64000707000005050707002a0a00000016019fb7588db46e193843a068758790caf90b0f6ce000»

Теперь разобьем все действия на шаги:

  • target-parameterType: В данном случае уже известно, что контракты MultisigNat и MultisigAdmin42 принимают параметр типа nat. 
  • target-parameter: контракт MultisigAdmin42 позволяет только отправлять параметр со значением 42, таким образом мы передадим его как наш основной параметр.
  • target-contract: Наша конечная цель — отправить параметр на $MULTISIG_ADMIN42_ADDRESS.
  • multisig-contract: контракт Multisig, который управляет нашим целевым адресом является $MULTISIG_NAT_ADDRESS
  • counter: Учитывая тот факт, что это первая транзакция, которую мы отправляем через MultisigNat, то счетчик стоит на значении 0. Если Вы не знаете правильное значение счетчика, Вы можете использовать следующую команду, чтобы получить верное значение. 

stack exec — lorentz-contract-multisig GenericMultisig get-counter-specialized —storageText «$(tezos-client get contract storage for $MULTISIG_NAT_ADDRESS)» —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»

 

  • signatures: В данный момент мы ничего не подписываем, таким образом аргумент остается пустым (“Nothing”). Через несколько шагов мы передадим сюда список с подписями. 
  • signerKeys: Это точно такой же список ключей, который использовался для создания контракта (в таком же порядке!). Дополнительно, функция get-counter-specialized, описанная выше в пункте ‘Counter’, подтвердит список публичных ключей, для правильного сопоставления с хранилищем.

Теперь мы используем сгенерированные байты, и подпишем их как Alice.

$ tezos-client sign bytes «0x0507070a0000001601b59c4c42c58363f113cec78c54535f59513e490d000707000005050707002a0a0000001601359bd24138e2baeb92e315f38dbab13b2ecc998100» for alice

 

Signature: edsigtkhfi4fUGivXsPpwqMByfza6XKnXeUW7NTEjXX8XmCXpcSi8XftaWJK6RA9nUzGz1sUFbiYxkqdxUFvd1Sxgc2MYS6ehE9

 

Далее мы сохраним подпись

$ OPERATION_SIGNATURE=»edsigtkhfi4fUGivXsPpwqMByfza6XKnXeUW7NTEjXX8XmCXpcSi8XftaWJK6RA9nUzGz1sUFbiYxkqdxUFvd1Sxgc2MYS6ehE9″

Теперь мы снова используем инструмент lorentz-contract-multisig, однако включив нашу подпись. Также важно отметить несколько пунктов:

  • Даже если Вы отсылаете  $OPERATION_SIGNATURE от Alice, то в любом случае можно создать транзакцию в виде перевода от $BOB_ADDRESS, которая будет идти на $MULTISIG_NAT_ADDRESS. Фактически, мы могли бы отправить эту транзакцию из $ FRED_ADDRESS, и пока у нас есть правильные подписи, она будет работать.
  • Важно отметить синтаксис аргумента для подписи. Структура должна идти в виде списка, который соответствует signerKeys, то есть для каждого signerKey должна быть соответствующая запись в списке подписей. В данном случае у нас есть только Alice, которая выполняет подпись. Alice является вторым публичным ключом в списке signerKeys, то есть структурируя наш список подписей, мы включим $OPERATION_SIGNATURE, который был подписан Alice, во вторую запись в списке. Так как Bob ничего не подписывает, мы добавим ‘Nothing’ в его индекс в списке. Таким образом у нас получится: «Just[Nothing,Just\»$OPERATION_SIGNATURE\»]». Если бы Bob подписывал, а Alice нет, в таком случае мы бы имели следующее: «Just[Just\»$OPERATION_SIGNATURE\»,Nothing]», и если бы оба администратора выполняли подпись, мы получили бы «Just[Just\»$BOB_SIGNATURE\»,Just\»$ALICE_SIGNATURE\»]». Ниже приведен более полный пример с двумя и более подписавшими администраторами. 
  • Нам нужно определить наш пункт перехода как ‘mainParemeter’.

$ tezos-client —wait none transfer 0 from $BOB_ADDRESS to $MULTISIG_NAT_ADDRESS   —entrypoint ‘mainParameter’ —arg «$(stack exec — lorentz-contract-multisig GenericMultisig run-multisig —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»» —multisig-contract «$MULTISIG_NAT_ADDRESS» —counter 0 —signatures «Just[Nothing,Just\»$OPERATION_SIGNATURE\»]» —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»)»   —burn-cap 0.000001

 

Waiting for the node to be bootstrapped before injection…

Current head: BKnRECdTRSYw (timestamp: 2020-04-10T18:25:57-00:00, validation: 2020-04-10T18:26:01-00:00)

Node is bootstrapped, ready for injecting operations.

Estimated gas: 46343 units (will add 100 for safety)

Estimated storage: no bytes added

Operation successfully injected in the node.

Operation hash is ‘ooCkwced2eA7xqM6HVaMRv9Ly6vjE99RnNuwhxodHXL2rMQiiSm’

NOT waiting for the operation to be included.

Use command

  tezos-client wait for ooCkwced2eA7xqM6HVaMRv9Ly6vjE99RnNuwhxodHXL2rMQiiSm to be included —confirmations 30 —branch BKnRECdTRSYwkvTYu5xUjxS3Km3naXvdThdLSfza2Rq6nfMz5nq

and/or an external block explorer to make sure that it has been included.

This sequence of operations was run:

  Manager signed operations:

    From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

    Fee to the baker: ꜩ0.005081

    Expected counter: 623946

    Gas limit: 46443

    Storage limit: 0 bytes

    Balance updates:

      tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm …………. -ꜩ0.005081

      fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,163) … +ꜩ0.005081

    Transaction:

      Amount: ꜩ0

      From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

      To: KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC

      Entrypoint: mainParameter

      Parameter: (Pair (Pair 0 (Left (Pair 42 «KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj»)))

                       { None ;

                         Some «edsigtkhfi4fUGivXsPpwqMByfza6XKnXeUW7NTEjXX8XmCXpcSi8XftaWJK6RA9nUzGz1sUFbiYxkqdxUFvd1Sxgc2MYS6ehE9» })

      This transaction was successfully applied

      Updated storage:

        (Pair 1

              (Pair 1

                    { 0x00622ace8f1d06165b951d0362624033e6f6eb5650c45290ff0ddbff6055d2caa1 ;

                      0x00cc80ab168b04973d9e1f9d4d2248b077a9250d3bce750b2735b4818a7b9bb7d3 }))

      Storage size: 873 bytes

      Consumed gas: 32561

    Internal operations:

      Transaction:

        Amount: ꜩ0

        From: KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC

        To: KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj

        Parameter: 42

        This transaction was successfully applied

        Updated storage: 0x01a74b12a982f45edfaa7f13b03a65ab6fab90bf6400

        Storage size: 149 bytes

        Consumed gas: 13782

 

Подписание Транзакции Двумя Участниками

В предыдущем примере мы подробно разобрали процесс подписи транзакции одним участником Alice. Теперь разберем как будет выглядеть такой же процесс, но с двумя участниками подписи.

В данном случае шаги являются очень схожими с шагами, которые используются для работы с одним участником.

В первую очередь необходимо сгенерировать новые байты. Мы не можем использовать байты, сгенерированные в предыдущем шаге, поскольку счетчик был увеличен, и мы выполнили отсылку транзакции на контракт MultisigNat.

$ stack exec — lorentz-contract-multisig GenericMultisig run-multisig  —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»»    —multisig-contract «$MULTISIG_NAT_ADDRESS»    —counter 1      —signatures «Nothing»     —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»

 

  «0x0507070a0000001601b59c4c42c58363f113cec78c54535f59513e490d000707000105050707002a0a0000001601359bd24138e2baeb92e315f38dbab13b2ecc998100»

Теперь Alice подпишет новые байты, и мы сохраним их как ALICE_SIGNATURE

$ tezos-client sign bytes «0x0507070a0000001601a74b12a982f45edfaa7f13b03a65ab6fab90bf64000707000105050707002a0a00000016019fb7588db46e193843a068758790caf90b0f6ce000» for alice 

 

Signature: edsigu7F7stg1Ct2z8x78bdvm1Z3RTD751HNJPydf1kEW6jEAi275py8GGp9fiMfz6d94bNEzH8qTx3bV7sMY976SRme4LhGWCn

 

$ ALICE_SIGNATURE=»edsigu7F7stg1Ct2z8x78bdvm1Z3RTD751HNJPydf1kEW6jEAi275py8GGp9fiMfz6d94bNEzH8qTx3bV7sMY976SRme4LhGWCn»

Bob выполнит те же действия, и мы также сохраним его подпись как BOB_SIGNATURE

$ tezos-client sign bytes «0x0507070a0000001601a74b12a982f45edfaa7f13b03a65ab6fab90bf64000707000105050707002a0a00000016019fb7588db46e193843a068758790caf90b0f6ce000» for bob

 

Signature: edsigtrCchePiqHWrGL77yknxaoo41RcbmNouRKhDWqaeezB4KxyLoUZZGvhEJnUfh6txFBhgYVDNyDdZaJEraNGKZaU1gsdNUX

 

$ BOB_SIGNATURE=»edsigtrCchePiqHWrGL77yknxaoo41RcbmNouRKhDWqaeezB4KxyLoUZZGvhEJnUfh6txFBhgYVDNyDdZaJEraNGKZaU1gsdNUX»

 

$ tezos-client —wait none transfer 0 from $BOB_ADDRESS to $MULTISIG_NAT_ADDRESS —entrypoint ‘mainParameter’ —arg «$(stack exec — lorentz-contract-multisig GenericMultisig run-multisig —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»» —multisig-contract «$MULTISIG_NAT_ADDRESS» —counter 1 —signatures «Just[Just\»$BOB_SIGNATURE\»,Just\»$ALICE_SIGNATURE\»]» —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key alice)\»]»)»   —burn-cap 0.000001

 

Waiting for the node to be bootstrapped before injection…

Current head: BLtJ6Xh46dTw (timestamp: 2020-04-10T19:29:09-00:00, validation: 2020-04-10T19:30:16-00:00)

Node is bootstrapped, ready for injecting operations.

Estimated gas: 46984 units (will add 100 for safety)

Estimated storage: no bytes added

Operation successfully injected in the node.

Operation hash is ‘opa7AcwvJJyZdMptL2tmanm1mFgZHEcPHfcfXiLFkK1jCxWDY6f’

NOT waiting for the operation to be included.

Use command

  tezos-client wait for opa7AcwvJJyZdMptL2tmanm1mFgZHEcPHfcfXiLFkK1jCxWDY6f to be included —confirmations 30 —branch BLtJ6Xh46dTwEiPQBRE83Ng9T17ufjfQwHSHS413KhjuzdJwW8P

and/or an external block explorer to make sure that it has been included.

This sequence of operations was run:

  Manager signed operations:

    From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

    Fee to the baker: ꜩ0.005249

    Expected counter: 623947

    Gas limit: 47084

    Storage limit: 0 bytes

    Balance updates:

      tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm …………. -ꜩ0.005249

      fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,163) … +ꜩ0.005249

    Transaction:

      Amount: ꜩ0

      From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

      To: KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC

      Entrypoint: mainParameter

      Parameter: (Pair (Pair 1 (Left (Pair 42 «KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj»)))

                       { Some «edsigtrCchePiqHWrGL77yknxaoo41RcbmNouRKhDWqaeezB4KxyLoUZZGvhEJnUfh6txFBhgYVDNyDdZaJEraNGKZaU1gsdNUX» ;

                         Some «edsigu7F7stg1Ct2z8x78bdvm1Z3RTD751HNJPydf1kEW6jEAi275py8GGp9fiMfz6d94bNEzH8qTx3bV7sMY976SRme4LhGWCn» })

      This transaction was successfully applied

      Updated storage:

        (Pair 2

              (Pair 1

                    { 0x00622ace8f1d06165b951d0362624033e6f6eb5650c45290ff0ddbff6055d2caa1 ;

                      0x00cc80ab168b04973d9e1f9d4d2248b077a9250d3bce750b2735b4818a7b9bb7d3 }))

      Storage size: 873 bytes

      Consumed gas: 33203

    Internal operations:

      Transaction:

        Amount: ꜩ0

        From: KT1PqLLxVURv2R4uRvtukngehoxeTXd7ySpC

        To: KT1P9GeN3vvVHEPKC4YKZAHTTFhLLdNM3toj

        Parameter: 42

        This transaction was successfully applied

        Updated storage: 0x01a74b12a982f45edfaa7f13b03a65ab6fab90bf6400

        Storage size: 149 bytes

        Consumed gas: 13781

 

Теперь мы успешно выполнили подпись с двумя администраторами. 

Подписание транзакции с неавторизованным участником 

В случае если кто-то не является администратором и пытается выполнить подпись, мы получим ошибку симуляции перевода. Попробуем использовать этот контракт Multisig, чтобы выполнить подпись от имени Fred.

$ stack exec — lorentz-contract-multisig GenericMultisig run-multisig  —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»» —multisig-contract «$MULTISIG_NAT_ADDRESS» —counter 4   —signatures «Nothing»   —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key fred)\»]»

 

«0x0507070a0000001601b59c4c42c58363f113cec78c54535f59513e490d000707000405050707002a0a0000001601359bd24138e2baeb92e315f38dbab13b2ecc998100»

 

$ tezos-client sign bytes «0x0507070a0000001601b59c4c42c58363f113cec78c54535f59513e490d000707000405050707002a0a0000001601359bd24138e2baeb92e315f38dbab13b2ecc998100» for fred

 

Signature: edsigthogogU5r8LPToExpzirPyH7j1zBz4AGNLxuscKtfcViUUyY9QFrxKvYE9GPquUJPnf32RcF4yutE3Em4ax9o8yNJoGZyg

 

$ FRED_SIGNATURE= «edsigthogogU5r8LPToExpzirPyH7j1zBz4AGNLxuscKtfcViUUyY9QFrxKvYE9GPquUJPnf32RcF4yutE3Em4ax9o8yNJoGZyg»

 

$ tezos-client —wait none transfer 0 from $BOB_ADDRESS to $MULTISIG_NAT_ADDRESS   —entrypoint ‘mainParameter’ —arg «$(stack exec — lorentz-contract-multisig GenericMultisig run-multisig —target-parameterType ‘nat’ —target-parameter ’42’ —target-contract «\»$MULTISIG_ADMIN42_ADDRESS\»» —multisig-contract «$MULTISIG_NAT_ADDRESS» —counter 4 —signatures «Just[Just\»$BOB_SIGNATURE\»,Just\»$FRED_SIGNATURE\»]» —signerKeys «[\»$(get_public_key bob)\»,\»$(get_public_key fred)\»]»)»   —burn-cap 0.000001

 

invalid signature(s) provided

CallStack (from HasCallStack):

  error, called at src/Lorentz/Contracts/GenericMultisig/CmdLnArgs.hs..

empty expression

Fatal error:

  transfer simulation failed

Обратите внимание, что перевод был отклонен с ошибкой «invalid signature(s) provided» (“неверная(ие) подпись(и)”). Сам контракт предусматривает, что публичный ключ Alice будет присутствовать в индексе 1, а ее подпись ( или ‘Nothing’) будет передана в список подписей в индекс 1. Пытаясь установить контроль (возможность управления) над контрактом под именем Fred, мы заменили открытый ключ и подпись Alice на Fred. Однако, контракт распознает эти действия и не сможет выполнить операцию. 

 

Не можете найти то, что искали?

Контакты

Готов работать с Tezos Ukraine?

Контакты