TIL 31 - Golang으로 블록체인 만들기(Mempool) 12

프동프동·2023년 2월 10일
0

TIL

목록 보기
31/46
post-thumbnail

BlockChain_study/exam38 at main · FDongFDong/BlockChain_study

Mempool(메모리풀)

아직 확정되지 않은 거래내역을 보관하는 곳

→ 아직 Confirm 받지 않은 Transaction들이 들어가는 곳

Mempool에 트랜잭션 생성하기

  • 소스 코드
    • blockchain/transaction.go
      type mempool struct {
      	Txs []*Tx
      }
      
      // 비어있는 mempool 생성
      var Mempool *mempool = &mempool{}
      
      type Tx struct {
      	Id        string   `json:"id"`
      	Timestamp int      `json:"timestamp"`
      	TxIns     []*TxIn  `json:"txins"`
      	TxOuts    []*TxOut `json:"txouts"`
      }
      
      type TxIn struct {
      	Owner  string `json:"owner"`
      	Amount int    `json:"amount"`
      }
      
      type TxOut struct {
      	Owner  string `json:"owner"`
      	Amount int    `json:"amount"`
      }
      
      // 유효한 트랜잭션을 생성하려면, 유저가 input에 돈이 들어있다는걸 보여주면 된다.
      // Transaction Input을 가져와서 Transaction Output을 만들면 해당 Transaction은 유효해진다.
      func makeTx(from, to string, amount int) (*Tx, error) {
      	// from의 잔고가 보내고자 하는 금액 보다 적으면 에러 출력
      	if Blockchain().BalanceByAddress(from) < amount {
      		return nil, errors.New("not enough money")
      	}
      	// 새로운 트랜잭션을 만들기 위해 txIns, txOuts을 생성한다.
      	var txIns []*TxIn
      	var txOuts []*TxOut
      
      	total := 0
      	// 이전 TxOut으로 TxInput을 만들기 위해 요청한 사용자의 TxOut List를 가져온다.
      	oldTxOuts := Blockchain().TxOutsByAddress(from)
      	// total값에 TxOut을 모아서 amount 값이 되도록 한다.
      	for _, txOut := range oldTxOuts {
      		if total > amount {
      			break
      		}
      		// 보내려는 값이 일치할 때 까지 
      		txIn := &TxIn{txOut.Owner, txOut.Amount}
      		txIns = append(txIns, txIn)
      		total += txIn.Amount
      	}
      	change := total - amount
      	// TxOut에게 줄 거스름돈이 있을 경우
      	if change != 0 {
      		changeTxOut := &TxOut{from, change}
      		txOuts = append(txOuts, changeTxOut)
      	}
      	txOut := &TxOut{to, amount}
      	txOuts = append(txOuts, txOut)
      	// 새로운 트랜잭션을 만들어준다.
      	tx := &Tx{
      		Id:        "",
      		Timestamp: int(time.Now().Unix()),
      		TxIns:     txIns,
      		TxOuts:    txOuts,
      	}
      	tx.getId()
      	return tx, nil
      }
      
      // 트랜잭션을 Mempool에 추가한다. 트랜잭션을 생성하지는 않는다.
      // 어떠한 이유로 트랜잭션을 블록에 추가할 수 없으면 error을 리턴해준다.
      func (m *mempool) AddTx(to string, amount int) error {
      	tx, err := makeTx("fdongfdong", to, amount)
      	if err != nil {
      		return err
      	}
      	// 트랜잭션이 정상적으로 만들어졌다면 Mempool에 추가해준다.
      	m.Txs = append(m.Txs, tx)
      	return nil
      }
    • rest/rest.go
      func mempool(rw http.ResponseWriter, r *http.Request) {
      	utils.HandleErr(json.NewEncoder(rw).Encode(blockchain.Mempool.Txs))
      }
      
      func transactions(rw http.ResponseWriter, r *http.Request) {
      	var payload addTxPayload
      	utils.HandleErr(json.NewDecoder(r.Body).Decode(&payload))
      	err := blockchain.Mempool.AddTx(payload.To, payload.Amount)
      	if err != nil {
      		json.NewEncoder(rw).Encode(errorResponse{"not enough funds"})
      	}
      	rw.WriteHeader(http.StatusCreated)
      }
      
      func Start(aPort int) {
      	router := mux.NewRouter()
      	port = fmt.Sprintf(":%d", aPort)
      	router.Use(jsonContentTypeMiddleware)
      	// ...
      	router.HandleFunc("/mempool", mempool).Methods("GET")
      	router.HandleFunc("/transactions", transactions).Methods("POST")
      	fmt.Printf("Listening on http://localhost%s\n", port)
      }
  • 실행 결과
    • 기능 : mempool에 들어있는 트랜잭션 확인
    • Method : GET
    • URL : http://localhost:4000/mempool
    • 시나리오
      • 기능 : 초기(블록체인) 상태 확인
      • Method : GET
      • URL : http://localhost:4000/status
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:44:25 GMT
        Content-Length: 115
        Connection: close
        
        {
          "newestHash": "00b904fb8d5a30754d81f8362b7bca54ba4d073689e8ab4af1d2be130bd085c1",
          "height": 1,
          "currentdifficulty": 2
        }
      • 기능 : 블록체인 내에 있는 블록 확인
      • Method : GET
      • URL : http://localhost:4000/blocks
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:45:02 GMT
        Content-Length: 342
        Connection: close
        
        [
          {
            "hash": "00b904fb8d5a30754d81f8362b7bca54ba4d073689e8ab4af1d2be130bd085c1",
            "height": 1,
            "defficulty": 2,
            "nonce": 172,
            "timestamp": 1672620199,
            "transactions": [
              {
                "id": "c7186f0a495a53ec522353da9aa9d2ff38e0f5c23e4cfd91b5b209fdd6582932",
                "timestamp": 1672620199,
                "txins": [
                  {
                    "owner": "COINBASE",
                    "amount": 50
                  }
                ],
                "txouts": [
                  {
                    "owner": "fdongfdong",
                    "amount": 50
                  }
                ]
              }
            ]
          }
        ]
      • 기능 : 잔고가 부족한 상태에서 전송(트랜잭션 생성)
      • Method : POST
      • URL : http://localhost:4000/transactions
        {
          "to" : "uou",
          "amount" : 80
        }
      • 결과
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:46:48 GMT
        Content-Length: 36
        Connection: close
        
        {
          "errorMessage": "not enough funds"
        }
      • 기능 : 잔고가 부족하므로 추가적인 채굴 진행
      • Method : POST
      • URL : http://localhost:4000/blocks
        {
          "message" : "Blockchain Test"
        }
      • 실행 결과
        HTTP/1.1 201 Created
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:48:32 GMT
        Content-Length: 0
        Connection: close
      • 기능 : 잔고 확인
      • Method : GET
      • URL : http://localhost:4000/balance/fdongfdong
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:49:18 GMT
        Content-Length: 39
        Connection: close
        
        {
          "address": "fdongfdong",
          "balance": 100
        }
      • 기능 : 송금 진행(트랜잭션 생성)
      • Method : POST
      • URL : http://localhost:4000/transactions
        {
          "to" : "uou",
          "amount" : 80
        }
      • 실행 결과
        HTTP/1.1 201 Created
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:50:34 GMT
        Content-Length: 0
        Connection: close
      • 기능 : Mempool 확인
      • Method : GET
      • URL : http://localhost:4000/mempool
      • 실행 결과
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 00:53:01 GMT
        Content-Length: 253
        Connection: close
        
        [
          {
            "id": "146702f253cf4cc4d5dfa0048302d6d3df07284a70fb940f589e15cb5651d36a",
            "timestamp": 1672620634,
            "txins": [
              {
                "owner": "fdongfdong",
                "amount": 50
              },
              {
                "owner": "fdongfdong",
                "amount": 50
              }
            ],
            "txouts": [
              {
                "owner": "fdongfdong",
                "amount": 20
              },
              {
                "owner": "uou",
                "amount": 80
              }
            ]
          }
        ]

Mempool에 들어있는 Transaction Confirm하기

BlockChain_study/exam39 at main · FDongFDong/BlockChain_study

  • 트랜잭션이 한번 사용되면 사용됨을 확인해줘야 중복으로 트랜잭션이 처리되지 않는다.
  • 실행 결과
    • 시나리오
      1. 채굴(Genesis Block)

        • Coinbase → 채굴자에게 보상으로 50개의 코인을 준다.
          • 트랜잭션 상태
            • TxIn : Coinbase
            • TxOutput
              • Owner : 채굴자
              • amount : 50개의 코인
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 09:21:05 GMT
        Content-Length: 351
        Connection: close
        
        [
          {
            "hash": "002aa5a286b488547cf01fa7a83f2b79d7d7e3aedc8b40d8f2f23b074e75867b",
            "height": 1,
            "defficulty": 2,
            "nonce": 397,
            "timestamp": 1672651048,
            "transactions": [
              {
                "id": "655c209e07851c4eda0911723c2129bb757f4c06dc00333c1a4bd674abfed6c6",
                "timestamp": 1672651048,
                "txins": [
                  {
                    "txid": "",
                    "index": -1,
                    "owner": "COINBASE"
                  }
                ],
                "txouts": [
                  {
                    "owner": "fdongfdong",
                    "amount": 50
                  }
                ]
              }
            ]
          }
        ]
      2. 블록 확인

        • 최근 생성된 블록의 해시값 확인
        • Height 확인
        • 현재 난이도 확인
          HTTP/1.1 200 OK
          Content-Type: application/json
          Date: Mon, 02 Jan 2023 09:20:38 GMT
          Content-Length: 115
          Connection: close
          
          {
            "newestHash": "002aa5a286b488547cf01fa7a83f2b79d7d7e3aedc8b40d8f2f23b074e75867b",
            "height": 1,
            "currentdifficulty": 2
          }
      3. 트랜잭션 생성

        • 채굴자가 가진 코인 50개 중 20개를 UserA에게 전송
          • 트랜잭션 상태
            • TxIn
              • 받는 사람 : fdongfdong
              • 트랜잭션 ID
            • TxOutput 1
              • 받는 사람 : UserA
              • 받는 코인의 개수 20개
            • TxOutput 2
              • 받는 사람 : fdongfdong
              • 받는 코인의 개수 30개
      4. Mempool에서 생성된 트랜잭션 확인

        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 09:25:45 GMT
        Content-Length: 292
        Connection: close
        
        [
          {
            "id": "09bd85d8a8c659ee4dfd2b5523cbd5a6471df91af779d41ea87d2689f7da97cb",
            "timestamp": 1672651543,
            "txins": [
              {
                "txid": "0209133b927dc28ab5a1b1f754dd14d90d24e5bc9aa812c2b4dc034b079eab9c",
                "index": 0,
                "owner": "fdongfdong"
              }
            ],
            "txouts": [
              {
                "owner": "fdongfdong",
                "amount": 30
              },
              {
                "owner": "UserA",
                "amount": 20
              }
            ]
          }
        ]
      5. 블록 생성하여 Mempool에 등록된 트랜잭션 Confirm하기

        • 생성된 블록에는 이전 블록의 값과 현재 생성된 블록 그리고 등록된 트랜잭션을 확인할 수 있다.
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 09:27:44 GMT
        Content-Length: 1067
        Connection: close
        
        [
          {
            "hash": "001fbc233299f18562c3829a12c22c2e51639758eefdac98222f4c927a82c4ea",
            "prevhash": "0025c38865745991d7ce214db74d02ff80f2c448451e5ed6f362ea362bd843b3",
            "height": 2,
            "defficulty": 2,
            "nonce": 28,
            "timestamp": 1672651657,
            "transactions": [
              {
                "id": "09bd85d8a8c659ee4dfd2b5523cbd5a6471df91af779d41ea87d2689f7da97cb",
                "timestamp": 1672651543,
                "txins": [
                  {
                    "txid": "0209133b927dc28ab5a1b1f754dd14d90d24e5bc9aa812c2b4dc034b079eab9c",
                    "index": 0,
                    "owner": "fdongfdong"
                  }
                ],
                "txouts": [
                  {
                    "owner": "fdongfdong",
                    "amount": 30
                  },
                  {
                    "owner": "UserA",
                    "amount": 20
                  }
                ]
              },
              {
                "id": "b2dacb15d958fa71d5a70d40082765c2d58dece9cc6b70a0885e85f13fb8c6c6",
                "timestamp": 1672651657,
                "txins": [
                  {
                    "txid": "",
                    "index": -1,
                    "owner": "COINBASE"
                  }
                ],
                "txouts": [
                  {
                    "owner": "fdongfdong",
                    "amount": 50
                  }
                ]
              }
            ]
          },
          {
            "hash": "0025c38865745991d7ce214db74d02ff80f2c448451e5ed6f362ea362bd843b3",
            "height": 1,
            "defficulty": 2,
            "nonce": 213,
            "timestamp": 1672651537,
            "transactions": [
              {
                "id": "0209133b927dc28ab5a1b1f754dd14d90d24e5bc9aa812c2b4dc034b079eab9c",
                "timestamp": 1672651537,
                "txins": [
                  {
                    "txid": "",
                    "index": -1,
                    "owner": "COINBASE"
                  }
                ],
                "txouts": [
                  {
                    "owner": "fdongfdong",
                    "amount": 50
                  }
                ]
              }
            ]
          }
        ]
        • 블록이 생성되어 Mempool은 비어있게 된다.
        HTTP/1.1 200 OK
        Content-Type: application/json
        Date: Mon, 02 Jan 2023 09:29:16 GMT
        Content-Length: 5
        Connection: close
        
        null
profile
좋은 개발자가 되고싶은

0개의 댓글