Pages:
Author

Topic: [BOUNTY]Cardstack - Blockchain. Hasta usd 350K (Read 291 times)

member
Activity: 784
Merit: 64
■ Professional Spanish Translator
NOTICIAS

El Director Fundador de Cardstack @christe se sentó con @queentatiana esta mañana para hablar sobre lo que hemos estado trabajando:

https://youtu.be/WZsdajfH1xo
member
Activity: 784
Merit: 64
■ Professional Spanish Translator
Estimados participantes de Cardstack Bounty,

Como ya anunciamos en el pasado, Cardstack brindará a todos los participantes la
opción de que sus recompensas se paguen en ETH en lugar de fichas de CARD.
Si desea tenerlo de esta manera, envíe este formulario la próxima semana

(hasta el 11.06.2018 a las 23:59 CEST)

Complete este formulario si desea recibir ETH en lugar de tokens CARD: ►Formulario◄

Tenga en cuenta que solo aceptaremos su solicitud si utiliza los mismos
detalles en la hoja de cálculo principal, incluida la misma dirección ETH.
member
Activity: 784
Merit: 64
■ Professional Spanish Translator



Website |Libro blanco |Facebook |Twitter | Telegram Ingles| Reddit| Blog



BUENAS NOTICIAS


Buenas Noticias: El contrato Inteligente de Cardstack
ha pasado las dos auditorías de seguridad por parte de
@NCCGroupInfosec, y oficialmente hemos abierto hoy
el código de contrato inteligente.


nota completa en:
https://medium.com/cardstack/cardstack-smart-contract-passes-ncc-audit-reaches-milestone-57e18ed90a76


member
Activity: 784
Merit: 64
■ Professional Spanish Translator



Website |Libro blanco |Facebook |Twitter | Telegram Ingles| Reddit| Blog



RECUERDE ESTE DATO DE SEGURIDAD



Ten cuidado con los estafadores. Nunca le pediremos que envíe fondos a
través de las redes sociales, correo electrónico o DM. No estamos haciendo
regalos gratis, ni ofrecemos bonos por esta vía.

Consulte https://cardstack.com para obtener la información más
reciente e infórmenos sobre cualquier actividad sospechosa en Telegram

member
Activity: 784
Merit: 64
■ Professional Spanish Translator
PENSAMIENTOS

La descentralización de Internet no ocurrirá repentinamente, sino gradualmente, y debemos construir para esa realidad.

Pensamientos de @christse en @beyondblocks



Nota completa en:
https://medium.com/cardstack/building-on-blockchain-for-the-real-world-92593b2a16ba
member
Activity: 784
Merit: 64
■ Professional Spanish Translator
¡Bienvenidos a los recién llegados!

¡Cardstack tendrá otro #AMA pronto! ¿Tiene alguna pregunta para nosotros? ¡No dude en preguntar cualquier cosa que tenga, y asegúrese de etiquetarlos con el hashtag #AMA!

Chris Tse, Director Fundador de Cardstack, responde preguntas de la comunidad en el #AMA anterior. Puedes verlo a continuación:
https://youtu.be/ULAprHGoSg8

IMPORTANTE: Cardstack NUNCA realizará o solicitará pagos a través de Telegram. La dirección de venta y preventa solo se publicará en el sitio web de Cardstack. No envíe ETH a ninguna dirección a través de Telegram.
member
Activity: 784
Merit: 64
■ Professional Spanish Translator


Amigo debes informar en el Bounty Oficial en Ingles.

no aqui.
member
Activity: 784
Merit: 64
■ Professional Spanish Translator
Amigos, les invito a leer esta interesante nota

CARDSTACK ES UN ECOSISTEMA DE SOFTWARE DESCENTRALIZADO
La empresa representa un salto adelante para Blockchain en cada capa de la pila de software, proporcionando un conjunto de herramientas que desbloquea el potencial de la Internet descentralizada para todos.




Aquí les dejo la nota completa:

https://medium.com/@kirochka84/cardstack-is-a-decentralized-software-ecosystem-58b58f5965e2
newbie
Activity: 2
Merit: 0
Hola,

Esta abierto todavía el registro para la WhiteList o llego tarde?

Por otro lado, el sistema de recompensas esta activo? (sobretodo el de twitter, facebook y Telegram)

Un saludo y gracias!
member
Activity: 112
Merit: 10
member
Activity: 784
Merit: 64
■ Professional Spanish Translator
Poniendolo todo junto

El enfoque que Cardstack está tomando para realizar contratos actualizables en Solidity incluye estas 3 características importantes:

Resguardo de estado en su propio(s) contrato(s).
Usar un contrato de registro para administrar direcciones de contrato y vincular contratos con su estado.
Resolución de búsquedas de nombre de ENS para direcciones de contrato.
Al adoptar estos enfoques para el desarrollo de contratos, Cardstack puede crear contratos que pueden evolucionar con el tiempo para satisfacer las necesidades cambiantes de las personas que usan nuestras aplicaciones distribuidas.

Esta es la primera de las optimistas actualizaciones que compartiremos sobre nuestra experiencia en Cardstack con Solidity.

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP

■ Criptoinversores LATAM

Youtube: http://bit.ly/2ndiNu7
Twitter: http://bit.ly/2nexRa0
Linkedin: http://bit.ly/2GimYgb


member
Activity: 784
Merit: 64
■ Professional Spanish Translator

La piedra angular de todo este proceso es el llamado Servicio de nombres de Ethereum (ENS). ENS permite que los contratos se referencien usando un nombre amigable para los humanos en lugar de una cadena de caracteres hexadecimales no amigable para los humanos https://ens.domains/. Esto permite a los usuarios interactuar con un contrato de token en la dirección cardstack.eth en lugar de la dirección 0x66406f50624a645f36faa517c39049200d55c56e; al igual que ser capaz de utilizar un nombre de dominio como https://google.com en lugar del dns original que dificil de recordar que es https://172.217.12.206.

El registro Cardstack se adhiere a EIP-137, que es el estándar que rige ENS, de modo que puede actuar como un “nombre de sesión” resolver (que es cómo ENS representa internamente nombres de contrato). Debido a que el registro ya está haciendo un seguimiento de la dirección de la última versión de cualquier contrato, usarlo como un resolver para ENS es una opción muy natural.

Como parte del registro de un contrato con el registro de Cardstack, el “namehash” del nombre del contrato se suministra a la función register().

Ese namehash luego se puede derivar de la cadena utilizando un script (ver https://github.com/danfinlay/eth-ens-namehash) que convierte el nombre del contrato complejo a uno amigable con los humanos. La dirección del contrato de registro se puede usar como la ENS de la resolución, de modo que resuelve la dirección de la última versión de un contrato de token para los nombres que se le presentan.


■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP

■ Criptoinversores LATAM

Youtube: http://bit.ly/2ndiNu7
Twitter: http://bit.ly/2nexRa0
Linkedin: http://bit.ly/2GimYgb

member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Cardstack usa un contrato base administratable.sol que proporciona la capacidad de agregar y eliminar administradores y súper administradores, así como modificadores para designar que las funciones solo pueden ser invocadas por administradores y superadministradores, o de forma más restrictiva, solo superadministradores. Además, se utilizan mapas iterables para que revisar introspectivamente las direcciones administrativas.

Code:
pragma solidity ^0.4.18;

import "zeppelin-solidity/contracts/ownership/Ownable.sol";
import "zeppelin-solidity/contracts/math/SafeMath.sol";

contract administratable is Ownable {
  using SafeMath for uint256;

  uint256 public totalAdminsMapping;
  uint256 public totalSuperAdminsMapping;
  mapping (uint256 => address) public adminsForIndex;
  mapping (uint256 => address) public superAdminsForIndex;
  mapping (address => bool) public admins;
  mapping (address => bool) public superAdmins;
  mapping (address => bool) processedAdmin;
  mapping (address => bool) processedSuperAdmin;

  event AddAdmin(address indexed admin);
  event RemoveAdmin(address indexed admin);
  event AddSuperAdmin(address indexed admin);
  event RemoveSuperAdmin(address indexed admin);

  modifier onlyAdmins {
    if (msg.sender != owner && !superAdmins[msg.sender] && !admins[msg.sender]) revert();
    _;
  }

  modifier onlySuperAdmins {
    if (msg.sender != owner && !superAdmins[msg.sender]) revert();
    _;
  }

  function addSuperAdmin(address admin) public onlyOwner {
    superAdmins[admin] = true;
    if (!processedSuperAdmin[admin]) {
      processedSuperAdmin[admin] = true;
      superAdminsForIndex[totalSuperAdminsMapping] = admin;
      totalSuperAdminsMapping = totalSuperAdminsMapping.add(1);
    }

    AddSuperAdmin(admin);
  }

  function removeSuperAdmin(address admin) public onlyOwner {
    superAdmins[admin] = false;

    RemoveSuperAdmin(admin);
  }

  function addAdmin(address admin) public onlySuperAdmins {
    admins[admin] = true;
    if (!processedAdmin[admin]) {
      processedAdmin[admin] = true;
      adminsForIndex[totalAdminsMapping] = admin;
      totalAdminsMapping = totalAdminsMapping.add(1);
    }

    AddAdmin(admin);
  }

  function removeAdmin(address admin) public onlySuperAdmins {
    admins[admin] = false;

    RemoveAdmin(admin);
  }
}

A modo de referencia, aparece el Registry.sol completo que muestra cómo se agrega el almacenamiento, cómo se registran y cómo se actualizan los contratos:

Code:
pragma solidity ^0.4.18;

import "zeppelin-solidity/contracts/ownership/Ownable.sol";
import "zeppelin-solidity/contracts/math/SafeMath.sol";
import "./upgradeable.sol";
import "./ExternalStorage.sol";
import "./CstLedger.sol";
import "./administratable.sol";
import "./configurable.sol";
import "./storable.sol";
import "./freezable.sol";
import "./ERC20.sol";

contract Registry is Ownable, administratable, upgradeable {
  using SafeMath for uint256;

  bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
  bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;

  uint256 public numContracts;
  mapping(bytes32 => address) public storageForHash;
  mapping(bytes32 => address) public contractForHash;
  mapping(bytes32 => bytes32) public hashForNamehash;
  mapping(bytes32 => bytes32) public namehashForHash;
  mapping(uint256 => string) public contractNameForIndex;

  event ContractRegistered(address indexed _contract, string _name, bytes32 namehash);
  event ContractUpgraded(address indexed successor, address indexed predecessor, string name, bytes32 namehash);
  event StorageAdded(address indexed storageAddress, string name);
  event StorageRemoved(address indexed storageAddress, string name);
  event AddrChanged(bytes32 indexed node, address a);

  function() public {
    revert();
  }

  function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
    return interfaceId == ADDR_INTERFACE_ID ||
           interfaceId == INTERFACE_META_ID;
  }

  function addr(bytes32 node) public view returns (address) {
    return contractForHash[hashForNamehash[node]];
  }

  function getContractHash(string name) public view unlessUpgraded returns (bytes32) {
    return keccak256(name);
  }

  function register(string name, address contractAddress, bytes32 namehash) public onlySuperAdmins unlessUpgraded returns (bool) {
    bytes32 hash = keccak256(name);
    require(bytes(name).length > 0);
    require(contractAddress != 0x0);
    require(contractForHash[hash] == 0x0);
    require(hashForNamehash[namehash] == 0x0);

    contractNameForIndex[numContracts] = name;
    contractForHash[hash] = contractAddress;

    if (namehash != 0x0) {
      hashForNamehash[namehash] = hash;
      namehashForHash[hash] = namehash;
    }

    numContracts = numContracts.add(1);

    address storageAddress = storageForHash[storable(contractAddress).getStorageNameHash()];
    address ledgerAddress = storageForHash[storable(contractAddress).getLedgerNameHash()];

    if (storageAddress != 0x0) {
      ExternalStorage(storageAddress).addAdmin(contractAddress);
    }
    if (ledgerAddress != 0x0) {
      CstLedger(ledgerAddress).addAdmin(contractAddress);
    }

    configurable(contractAddress).configureFromStorage();

    ContractRegistered(contractAddress, name, namehash);

    if (namehash != 0x0) {
      AddrChanged(namehash, contractAddress);
    }

    return true;
  }

  function upgradeContract(string name, address successor) public onlySuperAdmins unlessUpgraded returns (bytes32) {
    bytes32 hash = keccak256(name);
    require(successor != 0x0);
    require(contractForHash[hash] != 0x0);

    address predecessor = contractForHash[hash];
    contractForHash[hash] = successor;

    uint256 remainingContractBalance;
    // we need https://github.com/ethereum/EIPs/issues/165
    // to be able to see if a contract is ERC20 or not...
    if (hash == keccak256("cst")) {
      remainingContractBalance = ERC20(predecessor).balanceOf(predecessor);
    }

    upgradeable(predecessor).upgradeTo(successor,
                                       remainingContractBalance);
    upgradeable(successor).upgradedFrom(predecessor);

    address successorStorageAddress = storageForHash[storable(successor).getStorageNameHash()];
    address successorLedgerAddress = storageForHash[storable(successor).getLedgerNameHash()];
    address predecessorStorageAddress = storageForHash[storable(predecessor).getStorageNameHash()];
    address predecessorLedgerAddress = storageForHash[storable(predecessor).getLedgerNameHash()];

    if (successorStorageAddress != 0x0) {
      ExternalStorage(successorStorageAddress).addAdmin(successor);
    }
    if (predecessorStorageAddress != 0x0) {
      ExternalStorage(predecessorStorageAddress).removeAdmin(predecessor);
    }

    if (successorLedgerAddress != 0x0) {
      CstLedger(successorLedgerAddress).addAdmin(successor);
    }
    if (predecessorLedgerAddress != 0x0) {
      CstLedger(predecessorLedgerAddress).removeAdmin(predecessor);
    }

    configurable(successor).configureFromStorage();

    if (namehashForHash[hash] != 0x0) {
      AddrChanged(namehashForHash[hash], successor);
    }

    ContractUpgraded(successor, predecessor, name, namehashForHash[hash]);
    return hash;
  }

  function addStorage(string name, address storageAddress) public onlySuperAdmins unlessUpgraded {
    bytes32 hash = keccak256(name);
    storageForHash[hash] = storageAddress;

    StorageAdded(storageAddress, name);
  }

  function getStorage(string name) public view unlessUpgraded returns (address) {
    return storageForHash[keccak256(name)];
  }

  function removeStorage(string name) public onlySuperAdmins unlessUpgraded {
    address storageAddress = storageForHash[keccak256(name)];
    delete storageForHash[keccak256(name)];

    StorageRemoved(storageAddress, name);
  }
}

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP

■ Criptoinversores LATAM

Youtube: http://bit.ly/2ndiNu7
Twitter: http://bit.ly/2nexRa0
Linkedin: http://bit.ly/2GimYgb


member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Pero, ¿y los “permisos”?

Se ha mencionado la palabra “permisos” varias veces en esta publicación.

¿Qué quieren decir con eso? Los contratos Cardstack tienen la capacidad de designar direcciones desde las cuales las llamadas msg.send pueden invocar funciones privilegiadas. Además, cardstack ha diseñado dos niveles diferentes de acceso privilegiado (es muy probable que haya muchos más, y probablemente querrán generalizar más esta solución a medida que pase el tiempo). El rol de menor nivel de acceso privilegiado es lo que Hassan Abdel-Rahman llama un “administrador”, y el rol de mayor nivel de acceso privilegiado es lo que llama un “super administrador”.

En general, los administradores tienen la capacidad de modificar el almacenamiento, mientras que los superadministradores tienen la capacidad de crear administradores, registrar contratos y actualizar contratos.

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP



member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Entonces, un resumen rápido:

Se Agregó almacenamiento al registro y se asignó un nombre al almacenamiento.
Se creó un contrato (en este caso un contrato de token) que declara el interés en usar almacenamiento con un nombre específico.

Se registró un contrato con el registro, que luego resuelve los nombres del almacenamiento a direcciones específicas de Ethereum dentro del contrato que se registra.

upgradeContract()

La capacidad de actualizar un contrato queda expresada en la función upgradeContract(). Los parámetros de esta función son el nombre del contrato y la dirección del contrato “sucesor” (donde el contrato actual se convierte en el contrato predecesor).

El registro usará el mismo mecanismo que se aprovechó en el registro del contrato predecesor para descubrir el almacenamiento que el contrato sucesor ha declarado que está interesado en utilizar. El registro resuelve la dirección del almacenamiento en el contrato sucesor y vincula el almacenamiento dentro del contrato sucesor usando la función configureFromStorage().

Durante la operación de actualización, los permisos del contrato predecesor en el almacenamiento se revocan, de modo que ese contrato ya no puede manipular el almacenamiento. Del mismo modo, se otorgan los permisos del contrato sucesor sobre el almacenamiento, de modo que ese contrato puede manipular el almacenamiento. Además, el modificador,unlessUpgraded, evitará que se ejecuten las funciones de ese contrato predecesor y, en su lugar, hará que reviertan.

El contrato predecesor también adquiere una propiedad que apunta al contrato sucesor como resultado de la actualización del contrato del contrato, por lo que los clientes del contrato pueden descubrir la nueva dirección del actualizada. Finalmente, se emite un evento llamando a ContractUpgraded cuando se actualizan los contratos (así como un evento llamando aAddrChangedpara el soporte de resolución ENS EIP-137, más sobre esto más adelante).

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP



member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Como se puede observar, el nombre del libro mayor y el nombre de almacenamiento utilizados por el contrato del token se especifican en el constructor del contrato y luego se devuelven en la funciónstorable.sol Además, el token de contrato implementa una interfaz configurable.sol, que declara una función configureFromStorage(). En esta función, está el registro para resolver los nombres de almacenamiento a direcciones reales:

Code:
.
.

// In full disclosure, this is a simplification the actual function, i removed stuff
// that wasn't germane to the conversation around upgradable contracts

configureFromStorage() public onlySuperAdmins unlessUpgraded returns (bool) {
  address ledgerAddress = Registry(registry).getStorage(ledgerName);
  address storageAddress =  Registry(registry).getStorage(storageName);
  
  tokenLedger = ITokenLedger(ledgerAddress);
  externalStorage = storageAddress;
  
  return true;
}

.
.

Y en este momento ya se tiene un token de contrato que está vinculado a los tokens de almacenamiento para los que ha declarado interés.

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP




member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Después de implementar el contrato de almacenamiento, lo agregan al registro y asignan un nombre al contrato de almacenamiento, todo ello al llamar a la funciónregistry.addStorage(). De aquí en adelante, cuando los contratos se registran en el registro, pueden declarar su intención de usar el almacenamiento por su nombre. El registro es entonces responsable de resolver el nombre de almacenamiento en una dirección específica, así como otorgarle al contrato “permisos” para usar el almacenamiento (más sobre esto más adelante).

registry.registerContract()

Para los contratos que participan en el ecosistema y que no son contratos de almacenamiento, por ejemplo: El
contrato de tokens, usan la función registry.registerContract() para agregarlos a nuestro registro. Sus bcontratos implementan una interfaz storable.sol, que tiene la siguiente declaración:

Code:
pragma solidity ^0.4.18;

contract storable {
  function getLedgerNameHash() public view returns (bytes32);
  function getStorageNameHash() public view returns (bytes32);
}

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP

member
Activity: 784
Merit: 64
■ Professional Spanish Translator

El siguiente componente del enfoque actualizable de cardstack, es el registro. El registro crea una buena abstracción sobre las direcciones reales de Ethereum para los contratos que participan en nuestro ecosistema. La idea es que solo necesitamos saber el “nombre” de un contrato, y consultar el registro de la versión más reciente del contrato que tiene un nombre particular.

Además, los contratos que necesitan usar el almacenamiento compartido no necesitan conocer la dirección del almacenamiento compartido; más bien, pueden declarar al registro su interés en utilizar un cubo de almacenamiento en particular (que también tiene un nombre), y el registro se ocupará de vincular el almacenamiento al contrato que haya declarado interés en usarlo.

Entonces, a un nivel realmente alto, es el registro el que está haciendo el trabajo de mantener un registro de las direcciones de todos los contratos en nuestro sistema y mapear los nombres de los contratos en las direcciones de los contratos.

■ Programador

Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP



member
Activity: 784
Merit: 64
■ Professional Spanish Translator
Puede ver cómo usan su almacenamiento de contabilidad en el contrato principal de tokens ERC20. A continuación hay un ejemplo de algunas de las funciones del ERC20 que aprovechan el almacenamiento específico del libro mayor:

Code:
pragma solidity ^0.4.18;

import "zeppelin-solidity/contracts/ownership/Ownable.sol";
import "zeppelin-solidity/contracts/math/SafeMath.sol";
import "./ERC20.sol";
import "./freezable.sol";
import "./CstLedger.sol";
import "./ExternalStorage.sol";
import "./Registry.sol";
import "./CstLibrary.sol";
import "./displayable.sol";
import "./upgradeable.sol";
import "./configurable.sol";
import "./storable.sol";

contract CardstackToken is ERC20,
                           Ownable,
                           freezable,
                           displayable,
                           upgradeable,
                           configurable,
                           storable {

  using SafeMath for uint256;
  using CstLibrary for address;

  ITokenLedger public tokenLedger;
  address public externalStorage;

  .
  .
  .
 
 function totalSupply() public view unlessFrozen unlessUpgraded returns(uint256) {
    return tokenLedger.totalTokens();
  }

  function tokensAvailable() public view unlessFrozen unlessUpgraded returns(uint256) {
    return totalSupply().sub(totalInCirculation());
  }

  function balanceOf(address account) public view unlessUpgraded unlessFrozen returns (uint256) {
    address thisAddress = this;
    if (thisAddress == account) {
      return tokensAvailable();
    } else {
      return tokenLedger.balanceOf(account);
    }
  }

  function transfer(address recipient, uint256 amount) public unlessFrozen unlessUpgraded returns (bool) {
    require(amount > 0);
    require(!frozenAccount[recipient]);

    tokenLedger.transfer(msg.sender, recipient, amount);
    Transfer(msg.sender, recipient, amount);

    return true;
  }

  function mintTokens(uint256 mintedAmount) public onlySuperAdmins unlessFrozen unlessUpgraded returns (bool) {
    tokenLedger.mintTokens(mintedAmount);

    Mint(mintedAmount, tokenLedger.totalTokens(), circulationCap);

    Transfer(address(0), this, mintedAmount);

    return true;
  }

  function grantTokens(address recipient, uint256 amount) public onlySuperAdmins unlessFrozen unlessUpgraded returns (bool) {
    require(!frozenAccount[recipient]);

    tokenLedger.debitAccount(recipient, amount);
    Transfer(this, recipient, amount);

    return true;
  }
  
  .
  .
  .
  
}

■ Programador
Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP



member
Activity: 784
Merit: 64
■ Professional Spanish Translator

Otra cosa interesante a tener en cuenta es que: Han hecho un trabajo adicional en nuestro contrato de almacenamiento para permitir que nuestros libros mayores (y libros múltiples) sean iterables, de modo que el almacenamiento sea más fácilmente introspectado. Cuesta más gas para mantener tales estructuras; pero para los casos de uso específicos, entendieron que valía la pena compensar las tarifas adicionales de gas.

Para completar, la forma especializada del almacenamiento del libro mayor de cardstack, aparece a continuación:

Code:
pragma solidity ^0.4.18;

import "./administratable.sol";
import "zeppelin-solidity/contracts/math/SafeMath.sol";

contract ITokenLedger {
  function totalTokens() public view returns (uint256);
  function totalInCirculation() public view returns (uint256);
  function balanceOf(address account) public view returns (uint256);
  function mintTokens(uint256 amount) public;
  function transfer(address sender, address reciever, uint256 amount) public;
  function creditAccount(address account, uint256 amount) public;
  function debitAccount(address account, uint256 amount) public;
  function addAdmin(address admin) public;
  function removeAdmin(address admin) public;
}

contract CstLedger is ITokenLedger, administratable {

  using SafeMath for uint256;

  uint256 public _totalInCirculation; // warning this does not take into account unvested nor vested-unreleased tokens into consideration
  uint256 public _totalTokens;
  mapping (address => uint256) public _balanceOf;
  uint256 public ledgerCount;
  mapping (uint256 => address) public accountForIndex;
  mapping (address => bool) public accounts;

  function totalTokens() public view returns (uint256) {
    return _totalTokens;
  }

  function totalInCirculation() public view returns (uint256) {
    return _totalInCirculation;
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balanceOf[account];
  }

  function mintTokens(uint256 amount) public onlyAdmins {
    _totalTokens = _totalTokens.add(amount);
  }

  function makeAccountIterable(address account) internal {
    if (!accounts[account]) {
      accountForIndex[ledgerCount] = account;
      ledgerCount = ledgerCount.add(1);
      accounts[account] = true;
    }
  }

  function transfer(address sender, address recipient, uint256 amount) public onlyAdmins {
    require(_balanceOf[sender] >= amount);

    _balanceOf[sender] = _balanceOf[sender].sub(amount);
    _balanceOf[recipient] = _balanceOf[recipient].add(amount);
    makeAccountIterable(recipient);
  }

  function creditAccount(address account, uint256 amount) public onlyAdmins { // decrease asset/increase liability: remove tokens
    require(_balanceOf[account] >= amount);

    _totalInCirculation = _totalInCirculation.sub(amount);
    _balanceOf[account] = _balanceOf[account].sub(amount);
  }

  function debitAccount(address account, uint256 amount) public onlyAdmins { // increase asset/decrease liability: add tokens
    _totalInCirculation = _totalInCirculation.add(amount);
    _balanceOf[account] = _balanceOf[account].add(amount);
    makeAccountIterable(account);
  }
}

■ Programador
Hassan Abdel-Rahman
Developer at Cardstack

■ Links de la empresa

https://cardstack.com/
https://twitter.com/cardstack
https://www.facebook.com/cardstackproject
https://medium.com/cardstack

■ Chat Oficial de Telegram

Ingles: hIngles: https://t.me/cardstack
Español: Español: http://bit.ly/2FauvfP

Pages:
Jump to: