├── v0.4 ├── migrations │ ├── 1_initial_migration.js │ └── 2_deploy_client.js ├── contracts │ ├── Migrations.sol │ └── EthPrice.sol ├── package.json ├── test │ └── eth-price.js └── truffle-config.js ├── v0.5 ├── migrations │ ├── 1_initial_migration.js │ └── 2_deploy_client.js ├── contracts │ ├── Migrations.sol │ └── EthPrice.sol ├── package.json ├── test │ └── eth-price.js └── truffle-config.js ├── .gitignore ├── jobs └── eth-price.json └── README.md /v0.4/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /v0.5/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | npm-debug.log* 3 | 4 | # Runtime data 5 | pids 6 | *.pid 7 | *.seed 8 | *.pid.lock 9 | 10 | # Dependency or build-generated directories 11 | v0.4/node_modules/ 12 | v0.4/package-lock.json 13 | v0.4/build/ 14 | v0.5/node_modules/ 15 | v0.5/package-lock.json 16 | v0.5/build/ -------------------------------------------------------------------------------- /v0.4/migrations/2_deploy_client.js: -------------------------------------------------------------------------------- 1 | const EthPrice = artifacts.require("EthPrice"); 2 | 3 | const LINK_CONTRACT_ADDRESS = process.env.LINK_ADDRESS; 4 | const ORACLE_CONTRACT_ADDRESS = process.env.ORACLE_ADDRESS; 5 | 6 | module.exports = function(deployer) { 7 | deployer.deploy(EthPrice, LINK_CONTRACT_ADDRESS, ORACLE_CONTRACT_ADDRESS); 8 | }; 9 | -------------------------------------------------------------------------------- /v0.5/migrations/2_deploy_client.js: -------------------------------------------------------------------------------- 1 | const EthPrice = artifacts.require("EthPrice"); 2 | 3 | const LINK_CONTRACT_ADDRESS = process.env.LINK_ADDRESS; 4 | const ORACLE_CONTRACT_ADDRESS = process.env.ORACLE_ADDRESS; 5 | 6 | module.exports = function(deployer) { 7 | deployer.deploy(EthPrice, LINK_CONTRACT_ADDRESS, ORACLE_CONTRACT_ADDRESS); 8 | }; 9 | -------------------------------------------------------------------------------- /jobs/eth-price.json: -------------------------------------------------------------------------------- 1 | { 2 | "initiators": [ 3 | { 4 | "type": "RunLog", 5 | "params": { } 6 | } 7 | ], 8 | "tasks": [ 9 | { 10 | "type": "HTTPGet", 11 | "confirmations": 0, 12 | "params": { "get": "https://bitstamp.net/api/ticker/" } 13 | }, 14 | { 15 | "type": "JSONParse", 16 | "params": { "path": [ "last" ] } 17 | }, 18 | { 19 | "type": "Multiply", 20 | "params": { "times": 100 } 21 | }, 22 | { "type": "EthUint256" }, 23 | { "type": "EthTx" } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /v0.4/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.7.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v0.5/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.7.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v0.4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chainlink-sample", 3 | "version": "1.0.0", 4 | "description": "Truffle project demonstrating Kaleido Chainlink Decentralized Oracle service", 5 | "main": "truffle-config.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "address": "truffle exec addresses.js", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "license": "Apache-2.0", 15 | "devDependencies": { 16 | "truffle": "^5.1.9", 17 | "truffle-assertions": "^0.8.2" 18 | }, 19 | "dependencies": { 20 | "chainlink": "^0.7.10", 21 | "truffle-contract": "^3.0.8", 22 | "truffle-core": "^5.0.34", 23 | "truffle-environment": "^0.1.10", 24 | "web3": "^1.2.5-rc.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v0.5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chainlink-sample", 3 | "version": "1.0.0", 4 | "description": "Truffle project demonstrating Kaleido Chainlink Decentralized Oracle service", 5 | "main": "truffle-config.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "address": "truffle exec addresses.js", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "license": "Apache-2.0", 15 | "devDependencies": { 16 | "truffle": "^5.1.9", 17 | "truffle-assertions": "^0.8.2" 18 | }, 19 | "dependencies": { 20 | "chainlink": "^0.7.10", 21 | "truffle-contract": "^3.0.8", 22 | "truffle-core": "^5.0.34", 23 | "truffle-environment": "^0.1.10", 24 | "web3": "^1.2.5-rc.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v0.4/test/eth-price.js: -------------------------------------------------------------------------------- 1 | const EthPrice = artifacts.require('EthPrice'); 2 | 3 | const utils = require('web3-utils'); 4 | 5 | if (!process.env.LINK_ADDRESS) { 6 | console.error('Please set the LINK_ADDRESS environment variable using the value from Kaleido Chainlink service dashboard'); 7 | } 8 | 9 | if (!process.env.ORACLE_ADDRESS) { 10 | console.error('Please set the ORACLE_ADDRESS environment variable using the value from Kaleido Chainlink service dashboard'); 11 | } 12 | 13 | if (!process.env.JOB_ID) { 14 | console.error('Please set the JOB_ID environment variable after creating a new job specification in Chainlink using jobs/eth-price.json'); 15 | } 16 | 17 | contract("EthPrice", async (accounts) => { 18 | let myContract, myContractV4; 19 | 20 | describe("Solidity 0.4 based EthPrice contract", async() => { 21 | it("deploys the EthPrice contract", async() => { 22 | myContract = await EthPrice.deployed(); 23 | expect(myContract.address).to.match(/0x[0-9a-fA-F]{40}/); 24 | }); 25 | 26 | it(`Calling requestEthereumPrice() with job ID ${process.env.JOB_ID}`, async () => { 27 | let result = await myContract.requestEthereumPrice(process.env.JOB_ID); 28 | expect(result.receipt.transactionHash).to.match(/0x[0-9a-fA-F]{64}/); 29 | 30 | const blockNumber = result.receipt.blockNumber; 31 | 32 | const eventList = await myContract.getPastEvents("allEvents", {fromBlock: utils.toHex(blockNumber), toBlock: utils.toHex(blockNumber)}); 33 | const events = eventList.filter(ev => ev.transactionHash === result.receipt.transactionHash); 34 | expect(events.length).to.equal(1); // ChainlinkRequested 35 | expect(events[0].event).to.equal('ChainlinkRequested'); 36 | }); 37 | }); 38 | }); -------------------------------------------------------------------------------- /v0.5/test/eth-price.js: -------------------------------------------------------------------------------- 1 | const EthPrice = artifacts.require('EthPrice'); 2 | 3 | const utils = require('web3-utils'); 4 | 5 | if (!process.env.LINK_ADDRESS) { 6 | console.error('Please set the LINK_ADDRESS environment variable using the value from Kaleido Chainlink service dashboard'); 7 | } 8 | 9 | if (!process.env.ORACLE_ADDRESS) { 10 | console.error('Please set the ORACLE_ADDRESS environment variable using the value from Kaleido Chainlink service dashboard'); 11 | } 12 | 13 | if (!process.env.JOB_ID) { 14 | console.error('Please set the JOB_ID environment variable after creating a new job specification in Chainlink using jobs/eth-price.json'); 15 | } 16 | 17 | contract("EthPrice", async (accounts) => { 18 | let myContract, myContractV4; 19 | 20 | describe("Solidity 0.5 based EthPrice contract", async() => { 21 | it("deploys the EthPrice contract", async() => { 22 | myContract = await EthPrice.deployed(); 23 | expect(myContract.address).to.match(/0x[0-9a-fA-F]{40}/); 24 | }); 25 | 26 | it(`Calling requestEthereumPrice() with job ID ${process.env.JOB_ID}`, async () => { 27 | let result = await myContract.requestEthereumPrice(process.env.JOB_ID); 28 | expect(result.receipt.transactionHash).to.match(/0x[0-9a-fA-F]{64}/); 29 | 30 | const blockNumber = result.receipt.blockNumber; 31 | 32 | const eventList = await myContract.getPastEvents("allEvents", {fromBlock: utils.toHex(blockNumber), toBlock: utils.toHex(blockNumber)}); 33 | const events = eventList.filter(ev => ev.transactionHash === result.receipt.transactionHash); 34 | expect(events.length).to.equal(1); // ChainlinkRequested 35 | expect(events[0].event).to.equal('ChainlinkRequested'); 36 | }); 37 | }); 38 | }); -------------------------------------------------------------------------------- /v0.4/contracts/EthPrice.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | import "chainlink/contracts/ChainlinkClient.sol"; 4 | import "chainlink/contracts/vendor/Ownable.sol"; 5 | 6 | contract EthPrice is ChainlinkClient, Ownable { 7 | uint256 constant private ORACLE_PAYMENT = 0 * LINK; 8 | 9 | uint256 public currentPrice; 10 | 11 | event RequestEthereumPriceFulfilled( 12 | bytes32 indexed requestId, 13 | uint256 indexed price 14 | ); 15 | 16 | constructor(address _link, address _oracle) public Ownable() { 17 | setChainlinkToken(_link); 18 | setChainlinkOracle(_oracle); 19 | } 20 | 21 | function requestEthereumPrice(string _jobId) 22 | public 23 | onlyOwner 24 | { 25 | Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumPrice.selector); 26 | req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD"); 27 | req.add("path", "USD"); 28 | req.addInt("times", 100); 29 | sendChainlinkRequest(req, ORACLE_PAYMENT); 30 | } 31 | 32 | function fulfillEthereumPrice(bytes32 _requestId, uint256 _price) 33 | public 34 | recordChainlinkFulfillment(_requestId) 35 | { 36 | emit RequestEthereumPriceFulfilled(_requestId, _price); 37 | currentPrice = _price; 38 | } 39 | 40 | function getChainlinkToken() public view returns (address) { 41 | return chainlinkTokenAddress(); 42 | } 43 | 44 | function withdrawLink() public onlyOwner { 45 | LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress()); 46 | require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer"); 47 | } 48 | 49 | function cancelRequest( 50 | bytes32 _requestId, 51 | uint256 _payment, 52 | bytes4 _callbackFunctionId, 53 | uint256 _expiration 54 | ) 55 | public 56 | onlyOwner 57 | { 58 | cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration); 59 | } 60 | 61 | function stringToBytes32(string memory source) private pure returns (bytes32 result) { 62 | bytes memory tempEmptyStringTest = bytes(source); 63 | if (tempEmptyStringTest.length == 0) { 64 | return 0x0; 65 | } 66 | 67 | assembly { // solhint-disable-line no-inline-assembly 68 | result := mload(add(source, 32)) 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /v0.5/contracts/EthPrice.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | import "chainlink/v0.5/contracts/ChainlinkClient.sol"; 4 | import "chainlink/v0.5/contracts/vendor/Ownable.sol"; 5 | 6 | contract EthPrice is ChainlinkClient, Ownable { 7 | uint256 constant private ORACLE_PAYMENT = 0 * LINK; 8 | 9 | uint256 public currentPrice; 10 | 11 | event RequestEthereumPriceFulfilled( 12 | bytes32 indexed requestId, 13 | uint256 indexed price 14 | ); 15 | 16 | constructor(address _link, address _oracle) public Ownable() { 17 | setChainlinkToken(_link); 18 | setChainlinkOracle(_oracle); 19 | } 20 | 21 | function requestEthereumPrice(string memory _jobId) 22 | public 23 | onlyOwner 24 | { 25 | Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumPrice.selector); 26 | req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD"); 27 | req.add("path", "USD"); 28 | req.addInt("times", 100); 29 | sendChainlinkRequest(req, ORACLE_PAYMENT); 30 | } 31 | 32 | function fulfillEthereumPrice(bytes32 _requestId, uint256 _price) 33 | public 34 | recordChainlinkFulfillment(_requestId) 35 | { 36 | emit RequestEthereumPriceFulfilled(_requestId, _price); 37 | currentPrice = _price; 38 | } 39 | 40 | function getChainlinkToken() public view returns (address) { 41 | return chainlinkTokenAddress(); 42 | } 43 | 44 | function withdrawLink() public onlyOwner { 45 | LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress()); 46 | require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer"); 47 | } 48 | 49 | function cancelRequest( 50 | bytes32 _requestId, 51 | uint256 _payment, 52 | bytes4 _callbackFunctionId, 53 | uint256 _expiration 54 | ) 55 | public 56 | onlyOwner 57 | { 58 | cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration); 59 | } 60 | 61 | function stringToBytes32(string memory source) private pure returns (bytes32 result) { 62 | bytes memory tempEmptyStringTest = bytes(source); 63 | if (tempEmptyStringTest.length == 0) { 64 | return 0x0; 65 | } 66 | 67 | assembly { // solhint-disable-line no-inline-assembly 68 | result := mload(add(source, 32)) 69 | } 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /v0.4/truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * truffleframework.com/docs/advanced/configuration 10 | * 11 | * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) 12 | * to sign your transactions before they're sent to a remote public node. Infura accounts 13 | * are available for free at: infura.io/register. 14 | * 15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate 16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this 17 | * phrase from a file you've .gitignored so it doesn't accidentally become public. 18 | * 19 | */ 20 | const Web3 = require('web3'); 21 | 22 | module.exports = { 23 | /** 24 | * Networks define how you connect to your ethereum client and let you set the 25 | * defaults web3 uses to send transactions. If you don't specify one truffle 26 | * will spin up a development blockchain for you on port 9545 when you 27 | * run `develop` or `test`. You can ask a truffle command to use a specific 28 | * network from the command line, e.g 29 | * 30 | * $ truffle test --network 31 | */ 32 | 33 | networks: { 34 | // Useful for testing. The `development` name is special - truffle uses it by default 35 | // if it's defined here and no other network is specified at the command line. 36 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal 37 | // tab if you use this network and you must also set the `host`, `port` and `network_id` 38 | // options below to some value. 39 | // 40 | development: { 41 | provider: () => { 42 | return new Web3.providers.HttpProvider(process.env.ETH_URL); 43 | }, 44 | network_id: "*", // Any network (default: none) 45 | gasPrice: 0 46 | }, 47 | 48 | local: { 49 | host: "http://127.0.0.1", 50 | port: 7545, // Custom port 51 | network_id: "*", // Custom network 52 | gas: 8500000, // Gas sent with each transaction (default: ~6700000) 53 | gasPrice: 20000000000 // 20 gwei (in wei) (default: 100 gwei) 54 | }, 55 | }, 56 | 57 | // Set default mocha options here, use special reporters etc. 58 | mocha: { 59 | // timeout: 100000 60 | }, 61 | 62 | // Configure your compilers 63 | compilers: { 64 | solc: { 65 | version: "0.4.24", // Fetch exact version from solc-bin (default: truffle's version) 66 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 67 | settings: { // See the solidity docs for advice about optimization and evmVersion 68 | // optimizer: { 69 | // enabled: false, 70 | // runs: 200 71 | // }, 72 | evmVersion: "byzantium" 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /v0.5/truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * truffleframework.com/docs/advanced/configuration 10 | * 11 | * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) 12 | * to sign your transactions before they're sent to a remote public node. Infura accounts 13 | * are available for free at: infura.io/register. 14 | * 15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate 16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this 17 | * phrase from a file you've .gitignored so it doesn't accidentally become public. 18 | * 19 | */ 20 | 21 | const Web3 = require('web3'); 22 | 23 | module.exports = { 24 | /** 25 | * Networks define how you connect to your ethereum client and let you set the 26 | * defaults web3 uses to send transactions. If you don't specify one truffle 27 | * will spin up a development blockchain for you on port 9545 when you 28 | * run `develop` or `test`. You can ask a truffle command to use a specific 29 | * network from the command line, e.g 30 | * 31 | * $ truffle test --network 32 | */ 33 | 34 | networks: { 35 | // Useful for testing. The `development` name is special - truffle uses it by default 36 | // if it's defined here and no other network is specified at the command line. 37 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal 38 | // tab if you use this network and you must also set the `host`, `port` and `network_id` 39 | // options below to some value. 40 | // 41 | development: { 42 | provider: () => { 43 | return new Web3.providers.HttpProvider(process.env.ETH_URL); 44 | }, 45 | network_id: "*", // Any network (default: none) 46 | gasPrice: 0 47 | }, 48 | 49 | local: { 50 | host: "http://127.0.0.1", 51 | port: 7545, // Custom port 52 | network_id: "*", // Custom network 53 | gas: 8500000, // Gas sent with each transaction (default: ~6700000) 54 | gasPrice: 20000000000 // 20 gwei (in wei) (default: 100 gwei) 55 | }, 56 | 57 | // Useful for deploying to a public network. 58 | // NB: It's important to wrap the provider as a function. 59 | // ropsten: { 60 | // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), 61 | // network_id: 3, // Ropsten's id 62 | // gas: 5500000, // Ropsten has a lower block limit than mainnet 63 | // confirmations: 2, // # of confs to wait between deployments. (default: 0) 64 | // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) 65 | // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) 66 | // }, 67 | 68 | // Useful for private networks 69 | // private: { 70 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), 71 | // network_id: 2111, // This network is yours, in the cloud. 72 | // production: true // Treats this network as if it was a public net. (default: false) 73 | // } 74 | }, 75 | 76 | // Set default mocha options here, use special reporters etc. 77 | mocha: { 78 | // timeout: 100000 79 | }, 80 | 81 | // Configure your compilers 82 | compilers: { 83 | solc: { 84 | // version: "0.4.24", // Fetch exact version from solc-bin (default: truffle's version) 85 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 86 | settings: { // See the solidity docs for advice about optimization and evmVersion 87 | // optimizer: { 88 | // enabled: false, 89 | // runs: 200 90 | // }, 91 | evmVersion: "byzantium" 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Ejemplos de Smart Contracts para el servicio Kaleido Chainlink 2 | 3 | El servicio Chainlink de Kaleido es compatible con la popular tecnología Oracle descentralizada Chainlink . El servicio hace que sea trivial crear una red Chainlink autorizada adjunta a un entorno de cadena de bloques de Kaleido. 4 | 5 | El proyecto demuestra el código de contrato inteligente que un cliente debe escribir para utilizar el servicio de Oracle después de que Chainlink se haya aprovisionado en Kaleido. 6 | 7 | Se proporciona código de muestra para Solidity v0.4 y v0.5. 8 | 9 | ## Requisitos Previos 10 | 11 | Antes de ejecutar los ejemplos, asegúrese de que las siguientes herramientas estén instaladas: 12 | 13 | - __[node.js](https://nodejs.org/en/download/package-manager/)__ 14 | - __[truffle](https://www.trufflesuite.com/docs/truffle/getting-started/installation)__ 15 | 16 | Registrarse en kaleido: 17 | 18 | - __[kaleido](https://console.kaleido.io/login)__ 19 | 20 | ## Prueba de los ejemplos 21 | 22 | #### Aquí hay una descripción general de los pasos. 23 | 24 | 1. Cree un nodo Ethereum y un nodo Chainlink en su entorno Kaleido. 25 | 2. Cree un trabajo en el nodo Chainlink. 26 | 3. Establezca 4 `env` envvariables para conectar sus entornos: 27 | 28 | ``` 29 | JOB_ID 30 | ETH_URL 31 | LINK_ADDRESS 32 | ORACLE_ADDRESS 33 | ``` 34 | 35 | 4. Ejecute `npm i` y luego `truffle test` 36 | 37 | Vamos a desglosarlo. 38 | 39 | ### Crear un Trabajo en el Nodo ChainLink 40 | 41 | Después de agregar un servicio de Chainlink a un entorno de Kaleido, haga clic en el servicio para abrir el panel. Tome nota de la información esencial que se muestra para ejecutar los ejemplos: 42 | 43 | - LINK CONTRACT ADDRESS: la dirección de contrato para el token de enlace. Esto es necesario para implementar el contrato de cliente de Chainlink, pero no es necesario pagar LINK para usar el servicio de Oracle en un entorno de Kaleido. 44 | - ORACLE CONTRACT ADDRESS: la dirección del contrato de Oracle. Este es el componente central que hace que Chainlink funcione. Se debe informar al contrato de cliente de Chainlink en la muestra dónde se encuentra el contrato de Oracle para solicitar una ejecución de trabajo y se le debe devolver la llamada una vez que se completa la ejecución de trabajo. 45 | 46 | Haga clic en el botón **OPEN CHAINLINK WEB UI** para abrir la IU del operador de Chainlink. Utilice el nombre de usuario y la contraseña que se muestran en el panel de servicio para iniciar sesión. 47 | 48 | Después de iniciar sesión, haga clic en el botón "New Job", pegue el contenido JSON del archivo `chainlink-sample/jobs/eth-price.json`, y haga clic en **Create Job**. 49 | 50 | Copie el valor de la identificación del trabajo que generó Chainlink y configure una variable de entorno en la línea de comando `JOB_ID` con este valor. 51 | 52 | ### Configuración de la URL del nodo Ethereum de Kaleido 53 | 54 | La ejemplos de truffles de muestra implementará el contrato inteligente del cliente en el entorno de Kaleido de destino. Truffle necesita que le digan dónde está el nodo. 55 | 56 | Todos los nodos de la cadena de bloques de Kaleido están protegidos por sólidas credenciales de autenticación. En la interfaz de usuario de la consola de Kaleido, busque un nodo de su propiedad, busque el menú ... en el lado derecho y haga clic en **Connect**. Luego seleccione el botón en el lado izquierdo para **Native JSON/RPC**. Se le pedirá que genere un par de credenciales sólidas. Una vez generada, se muestra una página de tablero para diferentes formas de conectarse al nodo de Kaleido. Busque la URL completa en la parte inferior de la página bajo la etiqueta **CONNECTION URL**. Haga clic en **Copy**. 57 | 58 | Establezca la variable `ETH_URL` de entorno en el valor que acaba de copiar arriba. Esto será utilizado por `truffle-config.js` para apuntar las pruebas de trufas al nodo de Kaleido. 59 | 60 | ### Establecer Direcciones de Contrato de LinkToken y Oracle 61 | 62 | El contrato inteligente del cliente Chainlink requiere que las direcciones de los contratos LinkToken y Oracle funcionen. Estos valores se muestran en el panel de control del servicio Chainlink en la interfaz de usuario de la consola de Kaleido, como se explicó anteriormente. 63 | 64 | Copie esos valores y configúrelos en variables de entorno `LINK_ADDRESS` Y `ORACLE_ADDRESS` respectivamente. 65 | 66 | ### Ejecute los Trabajos de Chainlink 67 | 68 | El trabajo de Chainlink puede ser activado por el contrato inteligente del cliente a través del contrato de Oracle. Los detalles de cómo funciona el mecanismo se pueden encontrar en [esta publicación web](http://kaleido.io/blog). 69 | 70 | El Smart Contracts del cliente se puede escribir en Solidity v0.4 o v0.5. Se han proporcionado ejemplos para ambas versiones, en los directorios `v0.4` and `v0.5` respectivamente. 71 | 72 | Vaya al directorio de la versión de Solidity que le gustaría usar e instale primero las dependencias: 73 | 74 | ``` 75 | npm i 76 | ``` 77 | 78 | Luego puede ejecutar el ejemplo iniciando truffle test: 79 | 80 | ``` 81 | $ truffle test 82 | Using network 'development'. 83 | 84 | 85 | Compiling your contracts... 86 | =========================== 87 | ✔ Fetching solc version list from solc-bin. Attempt #1 88 | ✔ Downloading compiler. Attempt #1. 89 | > Compiling ./contracts/EthPrice.sol 90 | > Compiling ./contracts/Migrations.sol 91 | > Compiling chainlink/contracts/Chainlink.sol 92 | > Compiling chainlink/contracts/ChainlinkClient.sol 93 | > Compiling chainlink/contracts/interfaces/ChainlinkRequestInterface.sol 94 | > Compiling chainlink/contracts/interfaces/ENSInterface.sol 95 | > Compiling chainlink/contracts/interfaces/LinkTokenInterface.sol 96 | > Compiling chainlink/contracts/interfaces/PointerInterface.sol 97 | > Compiling chainlink/contracts/vendor/Buffer.sol 98 | > Compiling chainlink/contracts/vendor/CBOR.sol 99 | > Compiling chainlink/contracts/vendor/ENSResolver.sol 100 | > Compiling chainlink/contracts/vendor/Ownable.sol 101 | > Compiling chainlink/contracts/vendor/SafeMath.sol 102 | 103 | 104 | Contract: EthPrice 105 | Solidity 0.4 based EthPrice contract 106 | ✓ deploys the EthPrice contract (167ms) 107 | ✓ Calling requestEthereumPrice() with job ID 4149eac8974b4daabadc11ce4eb3da03 (9380ms) 108 | 109 | 110 | 2 passing (10s) 111 | 112 | 113 | ``` 114 | 115 | Para verificar que el trabajo se haya activado y ejecutado correctamente, vaya a la interfaz de usuario del operador de Chainlink y verifique las entradas de Ejecuciones del trabajo. Una ejecución exitosa debe tener un estado de `Complete`. 116 | 117 | ## **Bibliografía** 118 | 119 | - __[Youtube - Chainlink Networks en Kaleido](https://www.youtube.com/watch?v=qYzTmRj_Wwg)__ 120 | 121 | - __[Guía - Introducción a ChainLink](https://docs.kaleido.io/kaleido-services/3rd-party-services/chainlink/)__ 122 | 123 | - __[Guía - Haga que Ethereum funcione en minutos](https://docs.kaleido.io/using-kaleido/quick-start-ethereum/)__ 124 | 125 | - __[Guía - Cree su nueva Ethereum Blockchain](https://docs.kaleido.io/using-kaleido/quick-start-ethereum/first-blockchain/)__ 126 | 127 | - __[Guía - Emita su primera Transacción Ethereum](https://docs.kaleido.io/using-kaleido/quick-start-ethereum/first-ethereum/)__ 128 | --------------------------------------------------------------------------------