• SPV
    • Bitcoin Blockchain Size가 커짐에 따라 이를 저장하기 힘든 Light-Weight 노드 IoT 기기, 스마트폰 등에 Node 설치를 위해 나온 Node 운영 방안
    • Full Node로 부터 Merkle Tree와 Block Header만을 전송 받아 Transaction 검증
      • 네트워크에 참여하는 노드가 증가해야 풀노드 사용자도 네트워크에 참여할 이유가 생기기 때문. Light weight node(SPV) 가 존재
  • Merkle Pass
    • SPV node가 tx 검증을 위해 full node에게 요청하면, Full node는 Merkle pass 방식으로 tx를 검증
    • 모든 TX를 다 보내지 않고 merkle root를 검증할 방법.
    • 같이 hashing할 tx hash1과 검증할 tx hash, 다른 tx hash들이 해싱된 hash 값. 3가지를 이용해 merkle root를 구한다. blcok header의 merkle root와 비교해 검증.
  • Bloom Filter
    • Bloom Filter란 SPV 노드가 Bitcoin Full Node에게 관심있는 Transaction을 전달할 때, 내가 관심있는 Transaction을 숨기고 그 정보를 전달 받는 방법을 위한 기법
      • transaction 사이의 관계를 숨기기 위해서. bitmap에 transaction을 hash 함수를 3번 돌린 값을 기록. bitmap값을 가지고 있는 transaction(동일한 함수를 동일 횟수 돌렸을 때)은 spv노드가 관심있는 노드라는 것을 알 수 있음.
    • Bloom Filter는 False Positive 통해 관심이 없는 Transaction을 Client에서 제외시킬 수 있는 기능이다.
      • 관심있는 tx는 bitmap에 들어갈 수도있고 안들어 갈 수도 있지만. 관심없는 tx는 들어가지 않아 거를 수 있음
    • Bloom Filter는 Light Node가 Full Node에게 전달하여 Light Node가 관심있는 거래 정보를 실제로 드러내지 않고 Transaction 전달이 가능하도록 한다.
      • light node는 bloom filter를 full node에 전달하고 full node는 tx가 들어올 때 마다. bloom filter를 거쳐 해당하는 light node에게 tx를 전달한다.
  • Wallet Source Code
    def privateKeyToWif(key_hex):
    	return utils.base58CheckEncode(0x80, key_hex.decode('hex1))
    
    def privateKeyToPublicKey(s): #공개키 생성
    	sk = ecdsa.SigningKey.from_string(s.decode('hex' ), curve=ecdsa.SECP256kl) 
    	vk = sk.verifying_key
    	return ('\04' + sk.verifying_key.to_string()).encode('hex' ) 
    
    def pubKeyToAddr(s):
    	ripemdl60 = hashlib.new(1ripemdl60') #해싱
    	ripemdl60.update(hashlib.sha256(s.decode(hex')).digest()) 
    	return utils.base58CheckEncode(0, ripemdl60.digest())
    
    def keyToAddr(s):
    	return pubKeyToAddr(privateKeyToPublicKey(s)) #공개키 -> 사용자 개인키 -> 주소 생성
    
    # Warning: this  random function is  not cryptographically  strong and is  just for example
    private_key = ''.jotn(['%x' % random.randrange(16) for x in range(0, 64)])
    print keylltils.privateKeyToWif(private_key) #16진수로 변환
    print keylltils. keyToAddr( private_key) #address로 변환
    
    #  Makes a transaction from the inputs
    #  outputs is a list of [redemptionSatoshis, outputscript]
    # value값, script sig public key, sign sig, sign sig public key
    def makeRawTransaction(outputTransactionHash, sourceindex, scriptSig, outputs): 
    	def makeOutput(data):
    		#금액과 스크립트를 포함
    		redemptionSatoshis, outputScri.pt = data
    		return (struct.pack("<Q", redemptionSatoshis).encode('hex' ) + '%02x' % len(outputscript.decode('hex')) + outputscript)
    	formattedOutputs = ' 1. joi.n(map(makeOutput, outputs)) 
    	return (
    		#전체적인 transaction 구조를 포함.
    		"① 1000GMD0" + # 4 bytes version 
    		"01" + # varint for number of inputs
    		outputT ransactionHash.decode('hex' ) [::-l].encode(■hex1 ) + 
    		struct.pack('<L', sourceindex).encode('hex' ) +
    		'%02x' % len(scriptSig.decode('hex')) + scriptSig + 
    		"ffffffff" + # sequence
    		"%02x" % len(outputs) + # number of outputs formattedOutputs +
    		"00000000" # lockTime 
    	)
    
    # transaction 구조에 서명을 하는 함수
    def makesignedTransaction(privateKey, outputTransactionHash, sourceindex, scriptPubKey, outputs): 
    	myTxn_forSig = (makeRawTransaction(outputTransactionHash, sourceindex, scriptPubKey, outputs)
    		+ "01000000") # hash code
    	#hash 값
    	s256 = hashlib.sha256(hashlib.sha256(myTxn_forSig.decode(hex')).digest()).digest()
    	#sign key
    	sk = ecdsa.SigningKey.from_string(privateKey.decode('hex'), curve=ecdsa.SECP256kl) 
    	#sign
    	sig = sk.sign_digest(s256, sigencode=ecdsa.util.sigencode_der) + 1\011 # QI is hashtype 
    	pubKey = keylltils. privateKeyToPubHcKey( privateKey)
    	scriptSig = utils.varstr(sig).encode('hex') + utils.varstr(pubKey.decode('hex')).encode('hex') 
    	stgned_txn = makeRawTransaction(outputTransactionHash, sourceindex, scriptSig, outputs) 
    	verifyTxnSIgnature(signed_txn)
    	return signed_txn
    
    # sign data를 input에 포함
    privateKey = keyUtfls.wi.fToPrivateKey("5HusYj2b2x4nroApgfvaSfKYZhRbKFH41bVyPooymbC6KfgSXdD") #1MMMM 
    signed_txn = txnlltils.makeSignedTransaction(privateKey,
    	"81b4c832d70cb56ff957589752eb4125a4cab78a25a8fc52d6a09e5bd4404d48", # output (prev) transaction hash
    	0, # sourceindex
    	keyUtils.addrHashToScriptPubKey("lMMMMSUblpiy2ufrSguNUdFmAcvqrQF8M5"), 
    	[[91234, #satoshis
    	keyUtils.addrHashToScriptPubKey( ,,lKKKK6N21XKo48zWKuQKXdvSsCf95ibHFa")]]
    	)
    txnUtils.verifyTxnSignature(signed_txn) 
    print 'SIGNED TXN', signed_txn
    
    #어떤 네트워크 상에 있는 지 보여주는 값 (테스트넷, 메인넷)
    magic = 0xd9b4bef9
    
    #message로 전송.
    def makeMessage(magic, command, payload):
    	checksum = hashlib.sha256(hashlib.sha256(payload) .digest( )).digest( ) [0:4] 
    	return struct.pack('L12sL4s', magic, command, len(payload), checksum) + payload
    
    #message의 기본적인 주소
    def getVersionMsg(): 
    	version = 60002 
    	services = 1
    	timestamp = int( time. ti.me( ))
    	addr_me = utils.netaddr(socket.inet_aton("127.0.0.1"), 8333) 
    	addr_you = utils.netaddr(socket.inet_aton("127.0.0.1"), 8333) #받을 수 있는 노드의 정보
    	nonce = random.get randbits(64)
    	sub_version_num = utils.varstr(1' ) 
    	start_height = 0
    
    def getTxMsg(payload):
    	return makeMessage(magic, 'tx', payload)
    
    #소켓 통신을 위한 설정
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect(("97.88.151.164", 8333))
    sock.send(msgUtits.getVersionMsg( ))
    sock.recv(1000) # receive version
    sock.recv(1000) # receive verack
    #input, output이 완료된 tx를 전송
    sock.send(msgUtils.getTxMsg("010QQ00Q01484d40d45b9ea0d652fca8258ab7caa42541eb52975857f96fb50cd732c8b48100000QQ08a47304402202cb265bfl0707bf49346c3515dd3dl6fc454618c58ec0a0ff448a676c54ff71302206c6624d762alfce f4618284ead8fO8678ac05bl3c84235fl654e6adl68233e8201410414e301b2328fl7442c0b8310d787bf3d8a404cfbd0704fl3 5b6ad4b2d3ee751310f981926e53a6e8c39bd7d3fefd576c543cce493cbac06388f2651dlaacbfcdffffffff016264010000000 0001976a914c8e90996c7c6080ee06284600c684ed904dl4c5c88ac00000000".decode('hex')))
    
    #위의 모든 과정을 생략해주는 library의 사용.
    from bitcoiniib.wallets import Wallet 
    
    w = Wallet.create('Walletl')
    print(w.get_key().address)
    t = w.send_to(*lPWXhWvUH3bcDWn6Fdq3xhMRPfxRXTjAil,, '0.001 BTC*, offline=False) 
    print(t.info)
profile
"프로그래밍은 저의 상상을 실현 시킬 수 있는 유일한 도구입니다."

0개의 댓글