Но у меня возникли проблемы уже на создании первой транзакции, в ней указывается только совокупный объем списываемых средств и список участников (и количество подписей, необходимых для подтверждения транзакции... кстати непонятно, что будет если количество подписей будет меньше количества адресов, чьи тогда подписи не будут обязательны?). Самое странное что после подписывания транзакций участниками можно указывать объем, т.е. это объем, сколько зачислять на счет подписавшего? И непонятно как все участники будут контролировать, что объемы в транзакции верные?
Теперь вопрос, как действительно можно организовать выше описанную схему escrow? И что будет со средствами, если один из участников так и не подпишет транзакцию, есть ли возможность указать срок блокировки/действия транзакции, чтобы по его истечению средства были возвращены обратно? И самое главное, как можно создать транзакцию, в которой средства списываются одновременно с нескольких участников, например A -> 10 -> C, B -> 5 -> C, B -> 5 -> A или еще какие глупости...
Ну про то, что в geistgeld - я не в курсе, не смотрел.
Как уже выше писал, Escrow - это только одно из применений. В предыдущем посте я зря смешал его в кучу с OP_EVAL вообще.
Данное нововведение включает в себя две ключевые возможности:
1) отправление на специальный адрес, представляющий собой хэш скрипта. Скрипт предоставляется уже получающей стороной и с помощью OP_EVAL выполняется/проверяется.
2) отправление транзакции, содержащей в себе N публичных ключей и требующей подпись M из них. Стандартными средствами ожидается поддержка режимов 2-из-2 и 2-из-3.
Вот шаблоны возможных скриптов, "на которые" можно будет отправлять транзакции стандартным клиентом:
OP_PUBKEY << OP_CHECKSIG"Старый" режим, указывается полностью публичный ключ получателя. Самый первый из биткойновых скриптов, раньше он использовался при отправке биткойнов по айпи, сейчас в основном применяется только в генерирующих транзакциях.
Deepbit таким образом пересылает себе сдачу с выплат, т.к. сочетание этого режима с его ответной частью позволяет экономить около 9% объёма, занимаемого транзакциями.
Пример транзакции с таким скриптом на выходе:
http://blockexplorer.com/tx/750706968cb4ea66b792f001aecb48aac3536679f3b3a26ab6ccf70df3abdcc8OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIGНаиболее распространённый сейчас скрипт - отправка на хэш публичного ключа. Все обычные транзакции выглядят именно так.
Хэш публичного ключа в base58-кодировке и является биткойновым адресом, начинающимся на "1".
Пример транзакции с таким скриптом на выходе:
http://blockexplorer.com/tx/8346171ab636d38608b66102bb9db5384d2cce988191a117add33f3ebadfc4e4OP_DUP << OP_HASH160 << OP_SCRIPTHASH << OP_EQUALVERIFY << OP_EVALНовый тип - отправка на хэш скрипта. Сам скрипт предоставляется получателем. Если его хэш совпадает с указанным здесь значением, то скрипт исполняется.
Пример транзакции с таким скриптом на выходе:
http://blockexplorer.com/testnet/tx/f5eb769eff73a4781b600064ac16dff54e039994e7dedb77903a19b5edec1fc7(смотреть второй выход. блокэксплорер ещё не знает про OP_EVAL и поэтому отображает этот опкод как OP_NOP1)
OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIGНовый тип - указание N публичных ключей и количества требуемых подписей. Предположительно в "официальном" клиенте будут реализованы варианты "2-из-2" и "2-из-3". При этом не важно, какие именно два из трёх будут подписаны. Например - продавец и покупатель или продавец и доверенное лицо или покупатель и доверенное лицо.
После того как эта транзакция создана, "списать" средства с участников нельзя никак. Можно только определить, кому достанутся уже отправленные. Любой из них может создать свой вариант, но выполнен будет только тот, который окажется подписан нужным количеством подписей.
Более конкретный пример:
Алиса решает купить почку у Боба за 100 БТЦ. Для этого она должна создать транзакцию, содержащую в себе публичные ключи Алисы, Боба и Трента (доверенного лица). Указанную ей сумму изменить уже нельзя.
- Если сделка проходит успешно, то Боб создаёт транзакцию, которая берёт выход из Алисиной транзакции и переводит 99 БТЦ себе и 1 БТЦ Тренту за помощь (т.е. транзакция с двумя выходами). Он подписывает эту транзакцию своим приватным ключом и посылает её Алисе. Алиса подписывает её своим приватным ключом и транзакция срабатывает - получены две подписи из трёх.
- Если выясняется что Боб при жизни любил принять на грудь и продукт у него получился сомнительного качества, то Алиса может попробовать отказаться от сделки. Путём долгих и мучительных переговоров они решают вернуть 50%. Тогда Алиса создаёт транзакцию с выходами 50, 49 и 1 БТЦ соответственно, и они подписывают её.
- Боб попадает под троллейбус по пути в больницу и продукт приходит в негодность вместе с приватными ключами самого Боба, которые тот помнил наизусть. Тогда Трент создаёт транзакцию, возвращающую Алисе 90 БТЦ, посылающую 2 БТЦ себе и ещё 8 БТЦ в благотворительный фонд по борьбе с троллейбусами. Он подписывает её вместе с Алисой и она срабатывает без ключа Боба
- Трент решает уйти в монастырь и забрать с собой 100 БТЦ, отправленные Алисой. Он создаёт такую транзакцию, но Алиса и Боб её не подписывают. Ничего не происходит и они могут создать свой вариант - соответственно первому пункту
На данный момент поддержка автоматического создания таких транзакций не реализована в клиенте, но делать их можно с помощью предыдущего метода - через OP_EVAL. Поэтому я в прошлом посте упомянул их вместе.
Существующими средствами (если собрать биткойнд с новым патчем) это можно осуществить выполнением следующих RPC-команд:
getnewaddress (получаем наш новый адрес)
validateaddress 1ADYJVkbRSUSpm8YawB4pTknS6kNxGjiqL (эта команда проверяет наш адрес и показывает его полный публичный ключ)
addmultisigaddress 2 ["key1","key2","key3"] (эта команда берёт три публичных ключа в шестнадцатиричном или base58 формате и создаёт из них скриптовый адрес для OP_EVAL, реализующий схему 2-из-3, сами ключи я не показал. Подразумевается что мы используем один свой ключ и два чужих)
sendtoaddress 37muSN5ZrukVTvyVh3mT5Zc5ew9L9CBare 13.2p.s. в клиенте и протоколе похоже не предусмотрена возможность передачи больших чисел sig, получаемых после подписания участниками транзакции.. т.е. это придется делать через другие каналы связи.. это жутко неудобно и не секурно.
Не вижу проблемы с передачей.
Даже если бы пришлось передавать через другие каналы, то угрозы безопасности нет. Во-первых, если кто-то перехватит неподписанную или полуподписанную транзакцию - то пользы от неё никакой быть не может. Во-вторых, если он перехватит её и изменит в свою пользу, то подписывающие просто не станут её подписывать, т.к. увидят что выходы не те, что им нужны. В-третьих, если он перехватит уже подписанную транзакцию - то изменить её нельзя, подпись сразу испортится. К тому же нет смысла её перехватывать - она всё равно будет в блокчейне.