스위프트로 배우는 블록체인 - 탈중앙화 구현
노드모듈생성
지금까지는 하나의 네트워크에서 블록체인이 어떻게 작동하는지 알아보았습니다. 지금부터는 여러개의 노드를 만들어서 탈중앙화 개념을 구현해 보도록 하겠습니다. model.swift에 새로운 노드를 생성할 클래스를 아래와 같이 작성해 줍니다.
//새로운 노드 생성 클래스
class BlockchainNode : Codable {
var address : String
init(address : String) {
self.address = address
}
}
아래에 이이서 class Blockchain 부분에 아래에 위에서 만든 노드 데이터를 컨트롤할 변수와 추가할 함수를 만들어 준다.
//체인 구조체
class Blockchain : Codable {
//블록이 배열형태로 저장됨
private (set) var blocks : [Block] = [Block]()
//추가! 블록체인 데이터 구조에 블록체인 배열 값을 가지는 변수 생성
private (set) var nodes : [BlockchainNode] = [BlockchainNode]()
//추가! 블록체인 데이터 구조에 노드를 추가하는 함수
func addNode(_ node : BlockchainNode){
self.nodes.append(node)
}
마지막으로 이번에는 제일 위에서 만든 BlockchainNode 클래스에 아래와 같이 코드를 추가해 준다. 블록체인컨트롤.swift에서 웹브라우저로 넘어오는 request 데이터로 이 클래스를 초기화 해주기 위해서 아래 코드를 추가한다.
//새로운 노드 생성 클래스
class BlockchainNode : Codable {
var address : String
//BlockchainController.swift 에서 request 로 넘어오는 데이터로 초기화 하기 위한 초기화 함수
init?(request : Request){
guard let address = request.data["address"]?.string else {
return nil
}
self.address = address
}
init(address : String) {
self.address = address
}
}
노드등록
노드를 생성하는 함수를 만들었으니 이번에는 생성된 노드를 등록하는 함수를 구현해보겠습니다. BlockchainService 클래스로 가서 아래 코드를 추가해준다. //추가! 부분이다.
class BlockchainService {
//체인배열 변수
private (set) var blockchain : Blockchain!
//제네시스 블럭 초기화=
init() {
self.blockchain = Blockchain(genesisBlock: Block())
}
//추가! 생성한 노드를 블록체인에 추가하는 함수
func registerNode(_ node : BlockchainNode){
self.blockchain.addNode(node)
}
이어서 이제 BlockchainController.swift로 와서 func setupRoutes(){} 함수 부분에 웹브라우저를 통해서 노드를 등록하고, 등록한 노드를 확인해주는 로직을 작성해보겠다. 아래 소스 코드 참고.
private func setupRoutes(){
//노드 등록
self.drop.post("/nodes/register"){ request in
if let blockchainNode = BlockchainNode(request: request){
self.blockchainService.registerNode(blockchainNode)
}
return try JSONEncoder().encode(["msg":"노드 등록 성공"])
}
//노드 확인
self.drop.get("/nodes"){request in
let nodes = self.blockchainService.blockchain.nodes
return try JSONEncoder().encode(nodes)
}
테스트
위에 소스가 잘 작동을 하는지 포스트맨을 통해서 확인해보자~
등록된노드 확인 (8080,8088 등 여러개 등록해서 확인해보자)
여러 노드에서 마이닝 구현
vapor 프레임워크를 통해서 여러 포트의 서버를 등록해보겠다. 터미널을 열고 작업폴더에 위치한다음에
vapor run --port=8080, vapor run --port=8090, vapor run --port=8010 등 여러 서버가 가동되게 한다. 그리고 반드시 웹브라우저에서 확인 해야 한다.
마지막 구현
모든 노드들이 데이터를 공유하게 하기 위한 코드를 작성해보자. 일단 Blockchain 클래스에 blocks 변수 앞에 private 키워드 제거해준다.
//체인 구조체
class Blockchain : Codable {
//블록이 배열형태로 저장됨
var blocks : [Block] = [Block]()
service 부분에 아래 함수 추가
func resolve(completion : @escaping (Blockchain) -> ()){
let nodes = self.blockchain.nodes
for node in nodes{
let url = URL(string: "http://\(node.address)/blockchain")!
URLSession.shared.dataTask(with: url){ data,_, _ in
if let data = data{
let blockchain = try! JSONDecoder().decode(Blockchain.self, from: data)
if self.blockchain.blocks.count > blockchain.blocks.count{
completion(self.blockchain)
}else{
self.blockchain.blocks = blockchain.blocks
completion(blockchain)
}
}
}.resume()
}
}
controller 부분에 아래 함수 추가
private func setupRoutes(){
self.drop.get("/nodes/resolve"){request in
return try Response.async{
portal in
self.blockchainService.resolve(completion: { (blockchain) in
let blockchain = try! JSONEncoder().encode(blockchain)
portal.close(with: blockchain.makeResponse())
})
}
}
테스트
post맨을 열어서 한번더 테스트를 해보자.
'ios 뽀개기 > swift-blockchain' 카테고리의 다른 글
스위프트로 배우는 블록체인 - 채굴구현 (1) | 2018.06.02 |
---|---|
스위프트로 배우는 블록체인 - vapor프레임워크로 서버 만들기 (0) | 2018.06.01 |
스위프트로 배우는 블록체인 -스마트 컨트랙트 (0) | 2018.06.01 |
스위프트로 배우는 블록체인 -데이터구조 (0) | 2018.06.01 |
댓글