Bitcoin Forum

Local => Кодеры => Topic started by: babiypetr on July 22, 2017, 07:03:19 PM



Title: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on July 22, 2017, 07:03:19 PM
Доброго времени суток Уважаемые. Пробелы в знаниях завели в тупик( нужна помощь зала))

Допустим есть токен созданный на базе смарт контракта эфириума, этот самый контракт через переменную totalSupply получает количество монет которое будет создано этим контрактом, после деплоя контракта мы сможем через https://etherscan.io/tokens найти этот контракт, увидеть количество монет, и можем найти кто их сейчас держит и транзакции по передаче их, вроди бы все хорошо, но есть ли в виртуальной машине эфириума инструмент позволяющий отследить отдельную единицу этой массы  totalSupply?

Интересуюсь с целью сохранения статичных данных каждой монеты (дата выпуска, суммы привлеченные ею внутри ДАО и некоторые другие), возможно ли это? Или все таки эти монеты не более чем цифры внутри контракта?

Этот функционал нужен в рамках реализации проекта https://bitcointalk.org/index.php?topic=2034120.0

Наш GitLab: https://gitlab.babiy.pro/HelpCoin/Ethereum
Наш Redmine: https://redmine.babiy.pro/projects/dao-helpcoin


Title: Re: Вопрос к знатокам ETH
Post by: ferumflex on July 24, 2017, 06:24:22 AM
Эта информация должна записана быть в смартконтракте. Есть стандарт смартконтрактов ERC20 и в нем такой возможности нет. Если Вы хотите сделать что то похожее, то можно сделать функцию которая эмитирует монеты(естественно Вы должны передавать дополнительную информацию в смарт контракт) и эти монеты получают какой то ид\symbol и теперь чтобы кому то перевести нужно указать сартконтракту ид количество и кому. Думаю такое возможно но это не ERC20 и с добавлением на биржы будут проблемы, так как для бирж это отдельные токены


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on July 24, 2017, 06:48:12 AM
Эта информация должна записана быть в смартконтракте. Есть стандарт смартконтрактов ERC20 и в нем такой возможности нет. Если Вы хотите сделать что то похожее, то можно сделать функцию которая эмитирует монеты(естественно Вы должны передавать дополнительную информацию в смарт контракт) и эти монеты получают какой то ид\symbol и теперь чтобы кому то перевести нужно указать сартконтракту ид количество и кому. Думаю такое возможно но это не ERC20 и с добавлением на биржы будут проблемы, так как для бирж это отдельные токены

Да, Вы правы протокол ERC20 этого не поддерживает и в его обсуждениях на гитхабе тема эта поднималась, я задал подобный вопрос в обсуждении протокола ERC223 (https://github.com/ethereum/EIPs/issues/223), но увы и там они утверждают что снабдить каждую монету идентификатором будет очень дорого(( Хотя не сомненно такая возможность была бы весьма и весьма популярна, так как позволила бы выстраивать логику не только с контрактами но и с отдельными монетами...

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


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on July 24, 2017, 07:30:28 AM
Хотя по сути то задача действительно тривиальная (если конечно создаваемые монета не просто цифры в контракте):

1) Для всех генерируемых токенов в эфириуме вносится timestamp
2) В протокол ERC223 к функции transfer добавляется ещё один не обязательный аргумент bites _ident
3) Если кто то хочет использовать этот механизм он добавляет в функцию этот аргумент и тогда:
4) По событию event Transfer мы получаем в данных о транзакции данные о монетах в ней учавствовавших в виде примерно такого массива:

timestamp -> 1
timestamp -> 1
timestamp -> 0,5

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

P.S. Но это действительно должно стать неимоверно дорого, так как раздует размер транзакции до огромных размеров и значит довольно быстро такие транзакции упрутся в размер блока, и цена это защитный механизм ... Так что решения от разработчиков пока можно и не ждать... оно попросту нереализуемо в рамках существующей действительности...


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on July 25, 2017, 05:40:27 AM
Путем "вымучивания" разработчиков эфириума работающих над протоколом путем "нубских вопросов от новичка")) пришел к выводу что реализация задуманного все же возможна, и делается все на стороне моего приложения, для пользователя монета будет выглядеть как тысяча других, а вот проверка на нашем сайте сможет раскрыть тайну каждой монеты и даст возможность некоторые из монет перевести на свой отдельный кошелек. Какова будет цена "Gas" за это покажут эксперименты, позже отпишусь о результатах.

Quote
можно сделать функцию которая эмитирует монеты(естественно Вы должны передавать дополнительную информацию в смарт контракт) и эти монеты получают какой то ид\symbol и теперь чтобы кому то перевести нужно указать сартконтракту ид количество и кому.

Немного не так, монеты будут передаваться не зависимо от их идентификатора, самым обычным способом согласно протокола ERC20\ERC223 , идентификаторы монет участвующих в транзакции (отчисления 3% коммиссии) мы соберем в процессе и уже согласно этого разобьем суммы на части и отправим их первому владельцу монеты. То есть для пользования монетой идентификатор пассивен и выбирать какие монеты переводить не нужно.  

P.S. Поправьте если я снова ошибаюсь.


Title: Re: Вопрос к знатокам ETH
Post by: ferumflex on July 25, 2017, 08:59:10 AM
Да, можно и так. Просто зачем Вам вообще история монет? Что с ней можно сделать хорошего или где ее можно использовать?


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on July 25, 2017, 09:21:17 AM
Да, можно и так. Просто зачем Вам вообще история монет? Что с ней можно сделать хорошего или где ее можно использовать?

Просто со временем история отдельных монет может сделать некоторые из них уникальными, это больше инструмент популяризации монеты, она с виду вроди как и другие, но все же особая) А так как для возврата 20% кешбека от хождения идентификатор все же нужен , то привязать к нему немного истории не помешает. Хотя опять таки окончательные выводы сделаю после того как оценю расходы на такие транзакции, если эти расходы действительно будут значимыми , то от ряда плюшек придется отказаться, хотя можно реестры хранить и вне блокчейна, но не уверен что это правильно.

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

P.S. не заметил, что в данном топике не давал ссылку на проект , для которого собственно это все и делается, обновил первый пост добавив ссылку.

P.S.S. конечно же привлечь к этому делу профессионалов было бы куда продуктивнее, но спрос на них настолько велик, что их крайне сложно привлечь , особенно учитывая то , что проект не обещает привычных в данной отрасли "барышей" , вот поэтому и приходится на начальном этапе вникать в технические детали самостоятельно.. Благо есть опыт программирования в PHP .


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 07, 2017, 07:21:38 PM
Ребят, у меня снова кризис знаний( в голове все перемешалось... Киньте плиз ссылкой на пример или примерно черканите фрагмент кода, как все же добавить к токену timestamp ?

Quote
function MyAdvancedToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        uint256 ident = now
    ) token (initialSupply, tokenName, decimalUnits, tokenSymbol) {}

Это же не сработает? или это в функции генерации токенов добавляется?


Title: Re: Вопрос к знатокам ETH
Post by: imhoneer on August 08, 2017, 10:45:45 AM
Я вам предлагаю более простой вариант. Вот ролик https://www.youtube.com/watch?v=sPCPacV2JNU (https://www.youtube.com/watch?v=sPCPacV2JNU) как сделать лотерею на контрактах эфира со своими токенами. Там все подробно показано и рассказано. Вам вообще не недо будет заморачиваться.

Поэтому на базе этой схемы делаем следующую.

Вы выпускаете обычные токены в количестве 1,000,000 штук, выставляете цену для покупки в эфирах.

После этого вместо лотерейных билетов, выпускаете памятные токены с ценой 10 ваших обычных токенов за один памятный, количество памятных токенов устанавливается на 100,000 штук.

Обратите внимание, что в его примере контракта при покупке лотереи, есть массив с именем address, там и прописываете address[100000], начинается объяснение про него на 5мин10сек.

Этот массив и запоминает адреса всех покупателей.


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 08, 2017, 01:01:23 PM
Вы как всегда на высоте! Спасибо большое, если не ошибаюсь то то что я увидел - это то что я искал.

Мне нельзя выпускать отдельные токены и крепить их к основным, так как мне придется при каждой транзакции токена идентифицировать первого владельца, дабы отправить ему кешбек, но в реализации лотереи он показал как добавить этот идентификатор, пошел экспериментировать, посмотрим что из этого получится и сколько газа оно будет кушать))


Title: Re: Вопрос к знатокам ETH
Post by: imhoneer on August 08, 2017, 02:12:06 PM
Вы как всегда на высоте! Спасибо большое, если не ошибаюсь то то что я увидел - это то что я искал.

Мне нельзя выпускать отдельные токены и крепить их к основным, так как мне придется при каждой транзакции токена идентифицировать первого владельца, дабы отправить ему кешбек, но в реализации лотереи он показал как добавить этот идентификатор, пошел экспериментировать, посмотрим что из этого получится и сколько газа оно будет кушать))

Рад, что помог. В таком случае зайдите на аккаунт данного видеоблогера и посмотрите остальные видео. Он в них очень подробно всё объясняет.


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 09, 2017, 08:25:55 AM
Неожиданностью стало, что контракт генерирует токены исходя из decimalUnits , то есть если там стоит 18 , то при указании в initialSupply 1 000 000 мы не получаем миллион токенов, которые будут дробится а получаем 0.000000000001000000 токенов))  Я все верно понял так и должно быть? И на биржах в результате торгуется минимальная единичка? Или может быть альтернатива которая создаст токен по типу того же ETH ?


Title: Re: Вопрос к знатокам ETH
Post by: ferumflex on August 09, 2017, 09:58:36 AM
initial supply идет в минимальных единицах, для эфира это gwei, что соотвествует 10^-18 эфира.

На биржах торгуются целые токены, а не минимальная единица.

Чтобы Вам правильно рассчитать initial supply

initial supply = [кол-во токенов] * 10^[кол-во знаков после запятой]


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 09, 2017, 10:15:20 AM
initial supply идет в минимальных единицах, для эфира это gwei, что соотвествует 10^-18 эфира.

На биржах торгуются целые токены, а не минимальная единица.

Чтобы Вам правильно рассчитать initial supply

initial supply = [кол-во токенов] * 10^[кол-во знаков после запятой]

Спасибо большое, скажите а на практике сколько знаков после запятой достаточно? Что то 18 мне кажется перебор, вероятно есть какая то оптимальная цифра, понятно что она должна ориентироваться на ожидаемый курс монеты, но все же


Title: Re: Вопрос к знатокам ETH
Post by: ferumflex on August 10, 2017, 10:04:39 AM
Для токенов в основном ставят 8 знаков. Есть меньше есть больше, но думаю этого достаточно для любых целей.


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 10, 2017, 10:08:52 AM
Для токенов в основном ставят 8 знаков. Есть меньше есть больше, но думаю этого достаточно для любых целей.

Спасибо большое, так и сделаю. Скажите пожалуйста, кто либо использует для разработки Eclipse с плагином UML to Solidity ? Мне сам Eclipse нравится, но вот что то нормально с Solidity подружить у меня что то не очень выходит(


Title: Re: Вопрос к знатокам ETH
Post by: ferumflex on August 10, 2017, 10:13:51 AM
Я рекомендую пользоваться truffleframework, это не среда разработки а библиотека. А среда может быть любая.


Title: Re: Вопрос к знатокам ETH
Post by: babiypetr on August 10, 2017, 09:21:12 PM
В общем то отказался я от Eclipse, так и не победив его, систему разработки сделал так:

1) Sublime Text 3 + Solidity Plugin + Git Plugin - это локальный редактор
2) GitLab + Redmine - управление проектом и версиями
3) Truffle + Git + Geth - тестовая платформа

Сейчас пуш с Sublime Text обновляет файлы на GitLab а сервер с truffle в автомате подтягивает закомиченные изменения.

Решил посвятить эту ветку разработке своего проекта, поэтому и я надеюсь она когда то кому то будет полезна.
Чуть позже сделаю блог посвященный разработке и серверному окружению, так как по серверному окружению у меня есть чем поделится, я для своих проектов использую отказоустойчивый VDS кластер собранный в Public Cloud от OVH , довольно надежная штука получается.

Наш GitLab: https://gitlab.babiy.pro/HelpCoin/Ethereum
Наш Redmine: https://redmine.babiy.pro/projects/dao-helpcoin

Так же как и в основной ветке (https://bitcointalk.org/index.php?topic=2034120.0), приглашаю к участию в проекте разработчиков.


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 11, 2017, 12:22:05 PM
Оцените пожалуйста структуру проекта (https://gitlab.babiy.pro/HelpCoin/Ethereum/tree/master/contracts), не уверен, что поступил правильно, но решил сделать так:

1) Сущности сгруппировал по смыслу (отдельная директория для группы)
2) В каждой группе есть контроллер (контракт с суффиксом DAO)
3) Все контракты группы работают исключительно через свой контроллер
4) Контроллеры всех групп работают исключительно через контроллер ядра

Как думаете, не перестарался? на PHP я бы поступил именно так а тут вот не знаю насколько это оправданно 


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 14, 2017, 12:26:56 PM
Насколько я понимаю есть возможность в рамах дао принимать средства в других валютах? То есть понятно что это будет работать через внешнюю обвязку, но в целом это возможно? Можете дать ссылки на варианты реализации?


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 16, 2017, 07:58:43 AM
Скажите пожалуйста, а функция transfer работает по умолчанию с целыми единицами или с минимальными? Что то мне подсказывает что не с минимальными))


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 19, 2017, 08:59:37 AM
Тестирую контракт нужна помощь, вот сам контракт:

Code:
pragma solidity ^0.4.11;

import "./SafeMath.sol";

/**
 * IssueID 8
 */

contract ERC20Basic {
  uint256 public totalSupply;
  function balanceOf(address who) constant returns (uint256);
  function transfer(address to, uint256 value) returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) constant returns (uint256);
  function transferFrom(address from, address to, uint256 value) returns (bool);
  function approve(address spender, uint256 value) returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) returns (bool) {
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) constant returns (uint256 balance) {
    return balances[_owner];
  }

}
contract StandardToken is ERC20, BasicToken {
    
    string public standard;
    string public name;
    string public symbol;
    uint8  public decimals;
    uint256 public totalSupply;

    
    
  function StandardToken( uint256 initialSupply, string _standard, string _name, string _symbol, uint8 _decimals ){
        totalSupply = initialSupply;
        standard = _standard;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        balances[msg.sender] = initialSupply;
      }

  mapping (address => mapping (address => uint256)) allowed;


  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amout of tokens to be transfered
   */
  function transferFrom(address _from, address _to, uint256 _value) returns (bool) {
    var _allowance = allowed[_from][msg.sender];

    // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
    // require (_value <= _allowance);

    balances[_to] = balances[_to].add(_value);
    balances[_from] = balances[_from].sub(_value);
    allowed[_from][msg.sender] = _allowance.sub(_value);
    Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Aprove the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) returns (bool) {

    // To change the approve amount you first have to reduce the addresses`
    //  allowance to zero by calling `approve(_spender, 0)` if it is not
    //  already 0 to mitigate the race condition described here:
    //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    require((_value == 0) || (allowed[msg.sender][_spender] == 0));

    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifing the amount of tokens still available for the spender.
   */
  function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
    return allowed[_owner][_spender];
  }

}

contract HelpCoin is StandardToken {

    string  public _standard = "ERC20";
    string  public _name = "HelpCoin";
    string  public _symbol = "HLP";
    uint8   public _decimail = 8;
    uint256 public _initialSupply;
    uint256[] public _id;
    address[] public FirstOwner;
 
    address public ComissionAccount;

    event Commission(address indexed _to, uint256[] _id);
    event Debug(uint256 value);
    //event CalculateOut(uint256 amount);
      
    function HelpCoin( uint256 _initialSupply ) StandardToken(_initialSupply,_standard,_name,_symbol,_decimail){}
    
    
    function mintToken(address target, uint256 mintedAmount) {
//        setFirstOwner(target);
        balances[target] = balances[target].add(mintedAmount);
        totalSupply = totalSupply.add(mintedAmount);
        Transfer(0, this, mintedAmount);
        Transfer(this, target, mintedAmount);
    }

    function transfer(address _to, uint256 _value) returns (bool) {
        if (balances[msg.sender] < _value) { return false; }
        uint256 comiss = _value.div(100).mul(3);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[ComissionAccount] = balances[ComissionAccount].add(comiss);
        balances[_to] = balances[_to].add(_value.sub(comiss));
        Transfer(msg.sender, _to, _value);
        Commission(ComissionAccount, _id);
        return true;
    }

    function setCommissionAccount(address _CommissionAccount) {
      ComissionAccount = _CommissionAccount;
    }

    
//   function setFirstOwner(address target) {
//        FirstOwner = target;
//    }

}

Тестируется в частности функция transfer ,  она должна отчислять при переводе 3% на отдельный счет (контракт):
Code:
function transfer(address _to, uint256 _value) returns (bool) {
        if (balances[msg.sender] < _value) { return false; }
        uint256 comiss = _value.div(100).mul(3);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[ComissionAccount] = balances[ComissionAccount].add(comiss);
        balances[_to] = balances[_to].add(_value.sub(comiss));
        Transfer(msg.sender, _to, _value);
        Commission(ComissionAccount, _id);
        return true;
    }

Вот тест которым я это дело тестирую:
Code:
var HelpCoin = artifacts.require("HelpCoin");

contract('HelpCoin', function(accounts) {
    var hlp;

it("Deploy contract", function(done) {
var totalSupple = 100000000000;

HelpCoin.deployed(totalSupple).then(function(instance){
hlp = instance;
assert.isOk(hlp);
message = "Deployed address :" + hlp.address;
console.log(message);
done();
})
})
it("Перевод токенов с отчислением коммиссии", function(done){
var main_acc = accounts[0];
var target_acc = accounts[1];
var commiss_acc = accounts[2];

var main_bal_s;
var main_bal_e;
var target_bal_s;
var target_bal_e;
var commiss_bal_s;
var commiss_bal_e;

var ammount;
var commiss;

var message;

hlp.setCommissionAccount(commiss_acc).then(function(){
            return hlp.balanceOf.call(main_acc);
}).then(function(bal){
main_bal_s = bal.toNumber();
            message = "Start balance main account: " + main_bal_s + " HLP";
            console.log(message);
            return hlp.balanceOf.call(target_acc);
}).then(function(bal){
target_bal_s = bal.toNumber();
message = "Start balance target account: " + target_bal_s + " HLP";
console.log(message);
return hlp.balanceOf.call(commiss_acc);
}).then(function(bal){
commiss_bal_s = bal.toNumber();
message = "Start balance commiss account: " + commiss_bal_s + " HLP";
console.log(message);
ammount = 100;
message = "Transfer " + ammount + " HLP with 3% commission";
console.log(message);
return hlp.transfer(target_acc,ammount);
}).then(function(res){
message = "GasUsed for this transaction: " + res.receipt.gasUsed;
console.log(message);
return hlp.balanceOf.call(commiss_acc);
}).then(function(bal){
            commiss_bal_e = bal.toNumber();
            commiss = bal.toNumber();
            message = "The commssion comprised: " + commiss + " HLP";
            console.log(message);
return hlp.balanceOf.call(main_acc);
}).then(function(bal){
main_bal_e = bal.toNumber();
message = "End balance main account: " + main_bal_e + " HLP";
console.log(message);
return hlp.balanceOf.call(target_acc);
}).then(function(bal){
target_bal_e = bal.toNumber();
message = "End balance target account: " + target_bal_e + " HLP";
console.log(message);
message = "End balance commiss account: " + commiss_bal_e + " HLP";
console.log(message);

assert.equal(main_bal_e,main_bal_s - ammount,"Токены не переведены с главного аккаунта");
assert.equal(target_bal_e,target_bal_s + ammount - commiss,"Токены не переведены на принмающий аккаунт");
assert.equal(commiss_bal_e,target_bal_s + commiss,"Коммиссия не переведена");
done();
})
})
})

Согласно теста мы инициализируем 1000 HLP (100000000000 в минмальных единицах) и размещаем их на главном аккаунте, а потом переводим 100 HLP , результат теста:
Code:
root@helpcoin:/home/projects/HelpCoin/Testing# truffle test
Using network 'development'.

Compiling ./contracts/HelpCoin.sol...
Compiling ./contracts/SafeMath.sol...


  Contract: HelpCoin
Deployed address :0x1b92206f541de5b49a4e7914b0f4454d5ad78078
    ✓ Deploy contract
Start balance main account: 1000 HLP
Start balance target account: 0 HLP
Start balance commiss account: 0 HLP
Transfer 100 HLP with 3% commission
GasUsed for this transaction: 73839
The commssion comprised: 3 HLP
End balance main account: 900 HLP
End balance target account: 97 HLP
End balance commiss account: 3 HLP
    ✓ Перевод токенов с отчислением коммиссии (330ms)


  2 passing (371ms)

root@helpcoin:/home/projects/HelpCoin/Testing#

Как видно все отработало как надо, и судя из теста функция работает не с минимальными единицами, та как переместилось 100 HLP, но вот если мы уменьшим пересылаемое количество токенов до 10 то получаем проблему:
Code:
root@helpcoin:/home/projects/HelpCoin/Testing# truffle test
Using network 'development'.

Compiling ./contracts/HelpCoin.sol...
Compiling ./contracts/SafeMath.sol...


  Contract: HelpCoin
Deployed address :0xdb1934157218b2d927135261d72346d17d64c7af
    ✓ Deploy contract
Start balance main account: 1000 HLP
Start balance target account: 0 HLP
Start balance commiss account: 0 HLP
Transfer 10 HLP with 3% commission
GasUsed for this transaction: 58797
The commssion comprised: 0 HLP
End balance main account: 990 HLP
End balance target account: 10 HLP
End balance commiss account: 0 HLP
    ✓ Перевод токенов с отчислением коммиссии (353ms)


  2 passing (388ms)

root@helpcoin:/home/projects/HelpCoin/Testing#

Как видим трансфер токенов прошел успешно, но комиссия не расчиталась из-за того что в HLP она составляет (0.3 HLP) и по сути мы можем её отнять та как имеем 8 нулей в нашем токене, но перерыл всю документацию и та и не понял как же это сделать? Может очевидного не вижу... Помогите пожалуйста


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 19, 2017, 12:35:17 PM
Как всегда невнимательность и забывчивость сыграли со мною злую шутку( я совсем забыл про файл 2_helpcoin_migration.js
Code:
var HelpCoin =  artifacts.require("./HelpCoin.sol");

var initialSupply = 1000;
module.exports = function(deployer) {
deployer.deploy(HelpCoin,initialSupply);
};

В котором собственно и была указана эта злосчастная переменная с тысячей на борту, что собственно и ввело меня в заблуждение(((
Я исправил код:
Code:
var HelpCoin =  artifacts.require("./HelpCoin.sol");

var initialSupply = 1000*(10**8);
module.exports = function(deployer) {
deployer.deploy(HelpCoin,initialSupply);
};

А так же из теста убрал лишнее:
Code:
var HelpCoin = artifacts.require("HelpCoin");

contract('HelpCoin', function(accounts) {
    var hlp;

it("Deploy contract", function(done) {
HelpCoin.deployed().then(function(instance){
hlp = instance;
assert.isOk(hlp);
message = "Deployed address :" + hlp.address;
console.log(message);
done();
})
})
it("Перевод токенов с отчислением коммиссии", function(done){
var main_acc = accounts[0];
var target_acc = accounts[1];
var commiss_acc = accounts[2];

var main_bal_s;
var main_bal_e;
var target_bal_s;
var target_bal_e;
var commiss_bal_s;
var commiss_bal_e;

var ammount;
var commiss;

var message;

hlp.setCommissionAccount(commiss_acc).then(function(){
            return hlp.balanceOf.call(main_acc);
}).then(function(bal){
main_bal_s = bal.toNumber();
            message = "Start balance main account: " + main_bal_s + " HLP";
            console.log(message);
            return hlp.balanceOf.call(target_acc);
}).then(function(bal){
target_bal_s = bal.toNumber();
message = "Start balance target account: " + target_bal_s + " HLP";
console.log(message);
return hlp.balanceOf.call(commiss_acc);
}).then(function(bal){
commiss_bal_s = bal.toNumber();
message = "Start balance commiss account: " + commiss_bal_s + " HLP";
console.log(message);
ammount = 1000000000;
message = "Transfer " + ammount + " HLP with 3% commission";
console.log(message);
return hlp.transfer(target_acc,ammount);
}).then(function(res){
message = "GasUsed for this transaction: " + res.receipt.gasUsed;
console.log(message);
return hlp.balanceOf.call(commiss_acc);
}).then(function(bal){
            commiss_bal_e = bal.toNumber();
            commiss = bal.toNumber();
            message = "The commssion comprised: " + commiss + " HLP";
            console.log(message);
return hlp.balanceOf.call(main_acc);
}).then(function(bal){
main_bal_e = bal.toNumber();
message = "End balance main account: " + main_bal_e + " HLP";
console.log(message);
return hlp.balanceOf.call(target_acc);
}).then(function(bal){
target_bal_e = bal.toNumber();
message = "End balance target account: " + target_bal_e + " HLP";
console.log(message);
message = "End balance commiss account: " + commiss_bal_e + " HLP";
console.log(message);

assert.equal(main_bal_e,main_bal_s - ammount,"Токены не переведены с главного аккаунта");
assert.equal(target_bal_e,target_bal_s + ammount - commiss,"Токены не переведены на принмающий аккаунт");
assert.equal(commiss_bal_e,target_bal_s + commiss,"Коммиссия не переведена");
done();
})
})
})

И ура, теперь тест отработал так как и ожидалось:
Code:
root@helpcoin:/home/projects/HelpCoin/Testing# truffle test
Using network 'development'.

Compiling ./contracts/HelpCoin.sol...
Compiling ./contracts/SafeMath.sol...


  Contract: HelpCoin
Deployed address :0x9df17d35f384184057e8813252eb88a7e16128f3
    ✓ Deploy contract
Start balance main account: 100000000000 HLP
Start balance target account: 0 HLP
Start balance commiss account: 0 HLP
Transfer 1000000000 HLP with 3% commission
GasUsed for this transaction: 73967
The commssion comprised: 30000000 HLP
End balance main account: 99000000000 HLP
End balance target account: 970000000 HLP
End balance commiss account: 30000000 HLP
    ✓ Перевод токенов с отчислением коммиссии (313ms)


  2 passing (351ms)

root@helpcoin:/home/projects/HelpCoin/Testing#

Тест показывает что контракты все же работают с минимальными единицами, что в принципе снимает проблемы с вычислением процентов комиссии

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


Title: Re: [DEV]HelpCoin монета спасающая жизни!
Post by: babiypetr on August 21, 2017, 04:51:15 AM
И вот , недели изучения Solidity дали свои результаты - этих результата два, первый идентификатор к каждой монете добавить можно и второй - это неимоверно дорого(( . Но я распишу как добавлял его , возможно это кому то пригодится:
Code:
contract HelpCoin is StandardToken {

    string  public _standard = "ERC20";

    string  public _name = "HelpCoin";

    string  public _symbol = "HLP";

    uint8   public _decimail = 8;

    

    struct HLP {

      address FirstOwner;

      bytes32 CoinName;

      uint Date;

      uint Rating;

    }  

Структура данных HLP как раз призвана держать в себе данные о каждой монете
Code:
 

    address public ComissionAccount;

    mapping (address => mapping (uint256 => HLP)) public identificators;
Этот mapping как раз и сохраняет за каждым адресом (по аналогии с балансом) монеты вместе с их историей и прочими уникальными прелестями в таком формате : identificators[адрес][ид монеты - это ключ второй карты].FirstOwner|.CoinName|.Date|.Rating и по аналогии с тем же балансом нам нужно при трансфере токенов перемещать часть монет из адреса на адрес
Code:
      

    function HelpCoin( uint256 _initialSupply ) StandardToken(_initialSupply,_standard,_name,_symbol,_decimail) {

        setIds(_initialSupply,msg.sender,msg.sender,"preANN");

    }

    

    function setIds(uint256 total, address owner, address firstowner, bytes32 hlpname){

      uint256 timestamp = now;

        for (uint256 i = 0; i < total; i++ ) {

          identificators[owner][i] = HLP(firstowner,hlpname,timestamp,0);

        }

    }

Для теста я добавил функцию setIds которая заполняет эту карту данных при инициализации контракта, и при total = 100 (а у нас на минуточку 8 нолей после запятой, то есть 100  это капля в море) я получил "Out of gas" а вот при total = 10 все отработало как нужно. И думаю что причина тут не в цикле при помощи которого мы добавляем идентификатор и данные а именно в стоимости самого хранения такого количества информации в блокчейне...

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

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