前号の予告に変えて
前回の記事ではSwiftのSequenceプロトコルを取り上げたうえで,Sequence
の中でもランダムアクセス可能なCollection
を取り上げる予定でしたが,Sequence
を取り上げることにします。それも,Sequence
です。それはSwiftのコードにすれば,
protocol Block {
associatedtype Signature
associatedtype Payload
func isValid(prev:Self)->Bool
}
enum BlockError: Error {
case Invalid
}
protocol BlockChain : Sequence {
associatedtype Element:Block
var last:Element? { get }
mutating func append(_ block:Element)
throws
}
と表現されるSequence
,Sequence
です。
ブログでも発表したとおり,$BTC
)で売買する市場を備えたSNSで,
そしてそのビットコインは,
断言します。ブロックチェーンはWWW以来,
本誌の読者であれば,
と言っても慌てる必要はありません。ブロックチェーンが今後不可欠な基盤技術であることと受け入れられたのはごく最近なのですし,Nov '16
とあります。同社のチャートでさえこれしか歴史がないのです。今から学習しても十分間に合います。
Welcome to the blockchain!
ブロックチェーンとはいったい何か? 刻々と追記されるデータをP2Pネットワークで安全確実に同期する技術。これだけです。どうやってそれを実現しているかを知る前に,
「すでに記録が完了したデータ」
たとえばOSのインストーライメージであれば,ubuntu-16.
1384ac8f2c2a6479ba2a9cbe90a585618834560c477a699a4a7ebe7b5345ddc1
であることを確かめれば,
ファイルであれば,
適当にデータがたまったら,hashvalue
を署名とする最も簡単なブロックチェーンの実装です。
struct SimpleBlock<D:Hashable> : Block {
typealias Signature = Int
typealias Payload = D
let prevSign:Signature
let payload:D
func isValid(prev:SimpleBlock<D>)->Bool {
return prev.payload.hashValue == self.prevSign
}
}
struct SimpleBlockChain<D:Hashable> : BlockChain {
typealias Element = SimpleBlock<D>
var blocks:[Element]
var last:Element? {
return blocks.last
}
mutating func append(_ block:Element) throws {
if blocks.isEmpty ¦¦ block.isValid(prev: last!) {
blocks.append(block)
} else {
throw BlockError.Invalid
}
}
func makeIterator() -> AnyIterator<Element> {
var count = 0
return AnyIterator {
if count == self.blocks.count {
return nil
} else {
defer { count += 1 }
return self.blocks[count]
}
}
}
}
次の処理結果を見てのとおり,payload
のhashValue
が一致しないとappend
に失敗します。
extension SimpleBlockChain {
init() { blocks = [] }
}
var sbc = SimpleBlockChain<String>()
do {
try sbc.append( // 最初のブロック
SimpleBlock(prevSign: 0, payload: "Zero")
)
try sbc.append( // 次の不正なブロック
SimpleBlock(prevSign: 0, payload: "1")
)
} catch {
print(error)
}
try sbc.append(
SimpleBlock( // 次の正しいブロック
prevSign: 4799450038612711877,
payload: "one"
)
)
for b in sbc {
print(b.payload)
}
しかしこれだと,
しかしそれではフォークだらけになって収拾がつかなくなるのは目に見えています。それを防ぐにはどうしたら良いでしょう? ここで紙の世界を見てみましょう。複数のページからなる契約書があるとします。この契約書がひとつながりの契約書であることをどう保証しているか? 全ページに同じ人が署名するのです。実際には各ページにはイニシャル程度の略式の署名をし,