Azarus - это токенизированная игровая платформа, построенная на EOS. Вступая в этот стек технологий EOS, мы хотели поделиться процессом сборки и открытиями.
Следите за нами в:
web: https://azarus.io
twitter: https : //twitter.com/azarusio
Discord: https://discord.gg/ESma8zx
Как и в любом блокчейне, каждая транзакция, отправляемая узлам, подписывается закрытым ключом вызывающей стороны. Если вы кодировали на Ethereum / Solidity, вам, вероятно, пришлось добавить в свои контракты методы, устанавливающие и обновляющие адреса, которые были бы единственными разрешенными для некоторых критических функций. Одним из таких примеров является аварийный выключатель генерального директора в контрактах с криптокотиками…. который может быть вызван только генеральным директором.
Задачи игры Azarus, называемые внутри «кольцами», предъявляли некоторые особые требования:
* Контракт на кольцо должен иметь возможность получать депозит в монетах AZA и позволять выплату победителю или возмещение, если контракт не выполняется. не выполнено
* Внесенная сумма не должна быть доступна из других колец
* Клиентское приложение Dapp не может выполнять какие-либо операции по переводу монет, кроме внесения первоначальных средств
* Оракул, отвечающий за сообщение результаты игры должны иметь возможность инициировать выплату.
Это похоже на идеальную площадку для проверки нашего понимания схемы авторизации и делегирования EOS.
Подход, который мы использовали, сузился до создания «корзин» для депонирования средств… и обработки этих корзин как учетных записей, а не контрактов, что было бы ожидаемым подходом для других блокчейнов.
Поскольку мы сосредоточены на разрешительной стороне вещей, приведенный ниже код основан на eosjs, и мы проигнорируем фактическое содержание контрактов. Мы также создали прототип, используя монету EOS в качестве хранилища стоимости, в реальной производственной версии мы, очевидно, будем использовать вместо этого токен AZA.
Заключение договоров
Мы начинаем с публикации наших кольцевых контрактов
const eosioTokenClientAccount = await eos.newaccount({ creator: 'eosio', name: eosioToken, owner: eosioTokenClientPublic, active: eosioTokenClientPublic, recovery: 'eosio', deposit: '0 EOS'}); const eosioTokenClientContractPath = eosContractsPath + '/eosio.token/eosio.token'; const wast = fs.readFileSync(eosioTokenClientContractPath + '.wast') const abi = fs.readFileSync(eosioTokenClientContractPath + '.abi') const actions = await eos.getActions({ account_name:'eosio', pos: -1, offset: 0 }); try { const res_code = await eos.setcode(eosioToken, 0, 0, wast); const res_abi = await eos.setabi(eosioToken, JSON.parse(abi)); } catch(e) { console.log(e); } let eosioTokenContract = await eos.contract(eosioToken);
Затем мы создаем набор из 10 корзин в качестве новых учетных записей.
const nbMaxBucket = 10; var nbBucket = 0; for (i=1; i<6; i++) { for (j=1; j<6; j++) { const azaOracleBucket = 'azabucket' + i.toString() + j.toString(); const azaOracleBucketAccount = await eos.newaccount({ creator: azaOracle, name: azaOracleBucket, owner: azaBucketPublic, active: azaBucketPublic, recovery: azaOracle, deposit: '0 EOS'}); console.log("Account " + azaOracleBucket + " created"); const bucket_account = await eos.getAccount(azaOracleBucket); const permRes = await permission(azaOracle, azaOracleBucket, azaBucketPublic); const bucket_account2 = await eos.getAccount(azaOracleBucket); nbBucket++; if (nbBucket >= nbMaxBucket) { break; } } if (nbBucket >= nbMaxBucket) { break; } } console.log("Account and Contract created for " + azaOracle); } catch(err) { console.log(err); }
Авторизация Oracle
Эта следующая часть дает право Оракулу выплатить победителю розыгрыша, в конечном итоге получая доступ к средствам в корзине. Этот вызов должен выполняться из той же учетной записи «владельца», которая создала корзину.
async function permission(delegate, bucketName, publicKey) { try { const permRes = await eos.updateauth({ account: bucketName, permission: "active", parent: "owner", data: { threshold: 1, keys: [{key: publicKey, weight: 1}], accounts: [{permission:{ actor:delegate, permission:"active"}, weight:1}] }, delay: 0 }); return permRes; } catch(e) { console.log(e); return e; } }
Что действительно примечательно, так это то, что без необходимости предоставлять Oracle доступ к закрытому ключу корзины, мы разрешаем ему доступ как «активному» делегату.
В качестве дополнительной функции вы также можете каскадировать эти авторизации, создавая, например, разрешение «azarus», позволяющее delegate2 также получать доступ к корзине в качестве делегата начальному делегату.
const permRes2 = await eos.updateauth({ account: bucketName, permission: "azarus", parent: "active", data: { threshold: 1, keys: [{key: publicKey, weight: 1}], accounts: [{permission:{ actor:delegate2, permission:"active"}, weight:1}] }, delay: 0 });
Вращая колеса
Теперь у нас есть корзины, в которые вы можете вносить средства и где Oracle должен иметь возможность инициировать выплату ... давайте сделаем это
Вот как вы можете отправить монеты в ведро - ничего особенного, это простой перевод монет EOS.
const eosioTokenContract = await eos.contract('eosio.token'); const azaOracleBucket = 'azabucket11' let token_transfer_user = await eosioTokenContract.transfer({ from: userName, to: azaOracleBucket, quantity: prize + ' EOS', memo: 'deposit'}, { authorization: userName }); console.log("Payment from " + userName + " TO " + azaOracle + " for " + prize + ' -> OK');
А теперь последний штрих: Оракул вызывает ведро, чтобы приступить к выплате!
const eosioTokenContract = await eos.contract('eosio.token'); const azaOracleBucket = 'azabucket11' const bucket_account2 = await eos.getAccount(azaOracleBucket); let token_transfer_user = await eosioTokenContract.transfer({ from: azaOracleBucket, to: beneficiary, quantity: 100 + ' EOS', memo: 'deposit'}, { authorization: [{ actor: azaOracleBucket, permission: 'active', }], } );
Здесь Oracle смог перейти к выплате, только вызвав ведро, используя его идентификатор «azaOracleBucket», который ранее был настроен как делегат.
Вот схема архитектуры, которую мы только что собрали, с упором на расположение различных закрытых ключей (pKeys):
Вывод
Впечатляет то, как всего за несколько звонков мы можем создавать учетные записи и разрешать элементам системы взаимодействовать с ней без необходимости раскрывать или передавать их закрытый ключ. В конечном итоге это устраняет большую сложность самих контрактов, которые больше не отвечают за контроль доступа и могут сосредоточиться на обработке транзакционных данных, позволяя инфраструктуре EOS управлять контролем доступа!
Поделитесь своими мыслями и не стесняйтесь оспаривать наш подход - это новая платформа, и мы учимся по мере создания Azarus ... и по мере создания EOS!