Interfaz de acceso a la utilidades solc y swarm.
Implementación de la especificación ABI de Ethereum:
-
Codificación de llamadas a funciones
-
Decodificación de resultados devueltos
-
Decodificación de logs emitidos por el contract
-
Codificación de filter topics
Uso de Template Haskell para generar una interfaz Haskell de acceso a contracts programados directamente con el lenguaje Solidity. La interfaz Haskell incluye:
-
el objeto contract
-
función para su creación en el blockchain
-
funciones para llamar a los métodos del contract según las necesidades:
-
call para funciones pure o view
-
sendTx para funciones payable o nonpayable.
-
-
tipo de datos y función para decodificar los logs emitidos por el contract
-
tipo de datos y función para crear filters
-
función para verificar el código binario del contract almacenado en el blockchain
-
función para subir a swarm el metadata y los fuentes Solidity usados en la compilación
-
Posibilidad de generar interfaces para contracts almacenados en el blockchain.
-
Compilador solidity para compilar fuentes
-
Nodo Ethereum para la ejecución del monad Web3T
-
Nodo Swarm si se pretende subir el metadata o descargarlo durante la compilación
El contract Coin del proyecto hsoldapps está en el fichero fuente coin.sol:
pragma solidity ^0.4.0;
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Mint(address indexed to, uint amount);
event Sent(address indexed from, address indexed to, uint indexed amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() public {
minter = msg.sender;
}
function mint(address receiver, uint amount) public {
require(msg.sender == minter); //provoca fallo en eth_estimateGas
//if (msg.sender != minter) return;
balances[receiver] += amount;
Mint(receiver, amount);
}
function send(address receiver, uint amount) public {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Sent(msg.sender, receiver, amount);
}
}El fuente se compila en el modulo Coin.hs:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Ethereum.Solidity.Coin where
import Language.Haskell.TH
import Network.Web3.Dapp.EthABI.TH
import Network.Web3.Dapp.EthABI.Types
import System.Directory (getCurrentDirectory)
$(runIO getCurrentDirectory >>= \wd -> compile (SolcSettings [] [])
[ wd ++ "/src/Ethereum/Solidity/coin.sol"
])La compilación (ver documentación de la función compile) produce la siguiente interfaz Haskell:
data Coin_Event
= Coin_Mint (HexEthAddr, Uint256) |
Coin_Sent (HexEthAddr, HexEthAddr, Uint256)
deriving (Show)
data Coin_Event_Filter
= Coin_Mint_Filter (Maybe HexEthAddr) |
Coin_Sent_Filter (Maybe HexEthAddr, Maybe HexEthAddr, Maybe Uint256)
deriving (Show)
type Coin_minter_Out = HexEthAddr
type Coin_balances_In = HexEthAddr
type Coin_balances_Out = Uint256
type Coin_mint_In = (HexEthAddr, Uint256)
type Coin_send_In = (HexEthAddr, Uint256)
coin_contract :: Contract
coin_new_in :: HexData
coin_new_sendtx :: HexEthAddr -> (HexEthAddr, Maybe HexEthAddr, Maybe Integer, Maybe HexData)
coin_mint_in :: Coin_mint_In -> HexData
coin_mint_sendtx :: HexEthAddr -> HexEthAddr -> Coin_mint_In -> (HexEthAddr, Maybe HexEthAddr, Maybe Integer, Maybe HexData)
coin_send_sendtx :: HexEthAddr -> HexEthAddr -> Coin_send_In -> (HexEthAddr, Maybe HexEthAddr, Maybe Integer, Maybe HexData)
coin_send_in :: Coin_send_In -> HexData
coin_balances_out :: HexData -> Coin_balances_Out
coin_balances_in :: Coin_balances_In -> HexData
coin_balances_call :: (MonadBaseControl IO m, MonadLoggerIO m, JsonRpcConn c) => HexEthAddr -> HexEthAddr -> Coin_balances_In -> ReaderT * (Web3Session c m) (JsonRpcConnT c m) Coin_balances_Out
coin_minter_out :: HexData -> Coin_minter_Out
coin_minter_in :: HexData
coin_minter_call :: (MonadBaseControl IO m, MonadLoggerIO m, JsonRpcConn c) => HexEthAddr -> HexEthAddr -> ReaderT * (Web3Session c m) (JsonRpcConnT c m) Coin_minter_Out
coin_to_filter_topics :: Coin_Event_Filter -> [RpcEthFilterTopic]
coin_decode_log :: RpcEthLog -> Either Text Coin_Event
coin_from_log :: Text -> AbiValue -> Either Text Coin_Event
coin_guard :: (MonadBaseControl IO m, MonadLoggerIO m, JsonRpcConn c) => HexEthAddr -> Web3T c m ()
coin_swarm_upload :: IO (Either Text (HexHash256, [(FilePath, HexHash256)]))