Bitcoin Forum
May 10, 2024, 08:38:34 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 [2]  All
  Print  
Author Topic: [DEV]HelpCoin монета спасающая жизни!  (Read 1587 times)
babiypetr (OP)
Full Member
***
Offline Offline

Activity: 322
Merit: 102


View Profile WWW
August 16, 2017, 07:58:43 AM
 #21

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

I HATE TABLES I HATE TABLES I HA(╯°□°)╯︵ ┻━┻ TABLES I HATE TABLES I HATE TABLES
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715373514
Hero Member
*
Offline Offline

Posts: 1715373514

View Profile Personal Message (Offline)

Ignore
1715373514
Reply with quote  #2

1715373514
Report to moderator
babiypetr (OP)
Full Member
***
Offline Offline

Activity: 322
Merit: 102


View Profile WWW
August 19, 2017, 08:59:37 AM
 #22

Тестирую контракт нужна помощь, вот сам контракт:

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 нулей в нашем токене, но перерыл всю документацию и та и не понял как же это сделать? Может очевидного не вижу... Помогите пожалуйста

babiypetr (OP)
Full Member
***
Offline Offline

Activity: 322
Merit: 102


View Profile WWW
August 19, 2017, 12:35:17 PM
 #23

Как всегда невнимательность и забывчивость сыграли со мною злую шутку( я совсем забыл про файл 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#

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

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

babiypetr (OP)
Full Member
***
Offline Offline

Activity: 322
Merit: 102


View Profile WWW
August 21, 2017, 04:51:15 AM
 #24

И вот , недели изучения 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% от хождения монеты будут аккумулироваться на отдельном контракте и раз в месяц мы будем распределять собранные там токены между первыми владельцами пропорционально количеству токенов ими приобретенными .

Pages: « 1 [2]  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!