Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Концепция контракта
- pragma solidity ^0.4.11;
- import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
- /*
- Алгоритм
- 1) Клиент создает таск, и отправляет токены в общий баланс (в BigChainDB записывается количество токенов клиента)
- В процессе работы обновляем баланс клиента и баланс арендодателя
- 2) Когда арендодатель хочет вывести средства он с помощью оракула посылает на
- рест get запрос, пример: testapi.com?key= Адрес отправителя.
- Рест возвращает количество заработанных токенов для данного адреса по курсу, и затраченным рессурсам
- Арендодатель передает в get запрос свой адрес с помощью msg.sender (конструкция, которая хранит адрес отправителя)
- Это безопасно и таким образом никто не сможет вставить в get запрос другой адрес.
- 3) Рест возвращает из BigChainDB количество токенов для данного адреса,
- которые мы записываем в маппинг allowbalance, и после вывода средств обнуляем
- маппинг
- Проблема такого подхода
- Из-за того, что в Solidity нет простого способа перевести адрес в строку, чтобы
- создать URL для запроса, пользователь вынужден тратить много газа,
- Для снижения затрат будем использовать циклы instructional и functional assembly
- Они снизят потребление газа.
- Еще одна проблема
- Нужно обновлять баланс в BigChainDB после транзакций, чтобы не создать возможность двойной траты
- */
- contract Escrow is usingOraclize{
- // Адрес отправителя
- mapping (address=>string) public key;
- // Допустим адрес нашего рест
- string ourapi = "testapi.com?key=";
- // Количество токенов, которые может вывести определенный адрес
- mapping (address=>uint) public allowbalance;
- //Допустим это общий баланс
- mapping (address=>uint) public balance;
- // toAsciiString и char вспомогательные функции для преобразования adress в string
- function toAsciiString(address x) returns (string) {
- bytes memory s = new bytes(40);
- for (uint i = 0; i < 20; i++) {
- byte b = byte(uint8(uint(x) / (2**(8*(19 - i)))));
- byte hi = byte(uint8(b) / 16);
- byte lo = byte(uint8(b) - 16 * uint8(hi));
- s[2*i] = char(hi);
- s[2*i+1] = char(lo);
- }
- return string(s);
- }
- function char(byte b) returns (byte c) {
- if (b < 10) return byte(uint8(b) + 0x30);
- else return byte(uint8(b) + 0x57);
- }
- // Присвоение результата запроса
- /*
- function __callback(string result) {
- if (msg.sender != oraclize_cbAddress()) revert();
- // Вернет string нужно еще подумать как перевсти в int с минимальной потерей газа
- allowbalance[msg.sender] = result;
- updateValue();
- }
- */
- // Запрос
- /*
- function updateValue() payable {
- * Получив адрес в формате string мы можем создать URL запроса
- * ourapi + key[msg.sender]
- * для конкатенации используем метод oraclize strConcat
- * пример testapi.com?key=ca35b7d915458ef540ade6068dfe2f44e8fa733c
- key[msg.sender] = toAsciiString(msg.sender);
- if (oraclize_getPrice("URL") > this.balance) {
- LogNewOraclizeQuery("Если на кошельке недостаточно средств запрос не пройдет");
- } else {
- LogNewOraclizeQuery("Если средства есть, запрос будет отправлен, ждем результат");
- oraclize_query("URL", strConcat(ourapi, key[msg.sender]));
- }
- }
- */
- // Нас интересует эта небольшая часть кода
- // Примерно так это должно работать
- // Арендодатель делает запрос, передает свой aдрес в get
- function QueryToOracle() public{
- //updateValue();
- //Допустим он сделал запрос и получил 7 токенов
- allowbalance[msg.sender] = 7;
- }
- // После того, как запрос выполнен можно забирать средства
- function GetMoney() public{
- // Обновляем баланс
- balance[msg.sender] += allowbalance[msg.sender];
- // Вычитаем из общего баланса
- // balance["Адрес контракта с общим балансом"] -= allowbalance[msg.sender];
- // После перевода сбрасываем адрес и количество доступных для вывода токенов
- delete allowbalance[msg.sender];
- delete key[msg.sender];
- }
- }
Add Comment
Please, Sign In to add comment