본문 바로가기

옥탑방주인/Hyperledger

[Hyperledger Sawtooth] Transactions and Batches-sawtooth v1.0.4

Transactions and Batches


먼저 이 챕터를 시작하기 전에, 다른 파트에서 이 부분이 제일 중요하다고 언급이 계속해서 되고 있다.이 부분이 sawtooth의 제일 기본이며 중심역할을 하는 것 같으므로, 이 챕터를 확실히 이해하고 넘어가자.



상태 수정은 transaction을 작성하고 적용하여 수행됩니다. 클라이언트는 transaction을 생성하여 validator에 전송(submit)한다. validator는 state에서 변경시키는 transaction을 적용한다. 


Transaction은 항상 batch 안쪽에 포함되어 있다(wrapped). batch내의 모든 transaction은 state를 함께 처리하기도 하고, 전혀 처리하지 않기도 한다. 따라서, batch는 state 변화의 atomic unit이다.


Batch 및 transaction의 전체구조에는 Batch, BatchHeader, Transaction, TransactionHeader가 있다



Transaction Data Structure


Transaction은 프로토콜 버퍼(Protocol Buffer)를 serialized 한다. Transaction은 2가지 message types으로 구성되어 있다.

File: protos/transaction.proto

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

// Copyright 2016 Intel Corporation

//

// Licensed under the Apache License, Version 2.0 (the "License");

// you may not use this file except in compliance with the License.

// You may obtain a copy of the License at

//

//     http://www.apache.org/licenses/LICENSE-2.0

//

// Unless required by applicable law or agreed to in writing, software

// distributed under the License is distributed on an "AS IS" BASIS,

// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

// See the License for the specific language governing permissions and

// limitations under the License.

// -----------------------------------------------------------------------------


syntax = "proto3";


option java_multiple_files = true;

option java_package = "sawtooth.sdk.protobuf";

option go_package = "transaction_pb2";


message TransactionHeader {

    // Public key for the client who added this transaction to a batch

    string batcher_public_key = 1;


    // A list of transaction signatures that describe the transactions that

    // must be processed before this transaction can be valid

    repeated string dependencies = 2;


    // The family name correlates to the transaction processor's family name

    // that this transaction can be processed on, for example 'intkey'

    string family_name = 3;


    // The family version correlates to the transaction processor's family

    // version that this transaction can be processed on, for example "1.0"

    string family_version = 4;


    // A list of addresses that are given to the context manager and control

    // what addresses the transaction processor is allowed to read from.

    repeated string inputs = 5;


    // A random string that provides uniqueness for transactions with

    // otherwise identical fields.

    string nonce = 6;


    // A list of addresses that are given to the context manager and control

    // what addresses the transaction processor is allowed to write to.

    repeated string outputs = 7;


    //The sha512 hash of the encoded payload

    string payload_sha512 = 9;


    // Public key for the client that signed the TransactionHeader

    string signer_public_key = 10;

}


message Transaction {

    // The serialized version of the TransactionHeader

    bytes header = 1;


    // The signature derived from signing the header

    string header_signature = 2;


    // The payload is the encoded family specific information of the

    // transaction. Example cbor({'Verb': verb, 'Name': name,'Value': value})

    bytes payload = 3;

}


// A simple list of transactions that needs to be serialized before

// it can be transmitted to a batcher.

message TransactionList {

    repeated Transaction transactions = 1;

}



Header, Signature, and Public Keys


Transaction header field는 TransactionHeader의 serialized된 버전이다. header는 서명자(singer's)의 private key(transaction과 함께 전송되지 않는다)로 서명되어있고 서명의 결과는 header_signature에 저장된다. header는 transaction의 수신시 정확한 바이트가 서명되었는지에 대해 검증 될 수 있도록 serialized 된 형식으로 제공됩니다. 


verification process는 header_signature에 header bytes 결과에 서명된 signer_public key에 key를 확인한다. 


batcher_public_key 필드는이 transaction이 포함 된 batch에 서명하는 데 사용 된 공개 키(public key)와 일치해야합니다. 


serialized된 문서의 결과는 secp256k1 curve를 사용해서 transactor의 private ECDSA key와 함께 서명된다. 


validator는 64 바이트 "compact" 서명을 필요로 한다(64바이트로 압축된 서명을 말하는듯). 이것은 서명의 R과 S필드를 연결한 것 이다. 몇개의 라이브러리는 부수적인 header byte, ID field 복구, 또는 DER로 암호화된 서명된에 제공된다. Sawtooth는 서명이 64바이트가 아니라면 서명을 거절할 것이다.


노트 

전송자로부터 제작된 원본 header bytes는 서명의 확인(verification)을 위해 사용된다. 



Transaction Family


Hyperledger sawtooth에선, transaction의 묶음들은 transaction families라고 불리는 확장가능한 시스템(extensible system)으로 부터 정의된다. 새로운 transaction family를 정의하고 구현하면 적용 가능한 transaction의 분류법이 추가된다. 예를 들어, 자신 transaction family를 작성하는 방법을 보여주는 특정 언어(Application Developer 's Guide 참조)에서 tic-tac-toe를 재생하기위한 transaction 세트를 정의하는 "xo"라는 transaction family을 정의합니다. 


transaction family (family_name)의 이름 외에도 각 transaction family 버전 문자열 (family_version)을 지정합니다. 버전 문자열(version string)을 사용하면 업그레이드 할 네트워크의 노드를 조정하면서 transaction family을 업그레이드 할 수 있습니다.



Dependencies and Input/Output Addresses


transaction은 다른 transaction에 의존 할 수 있습니다. 즉 종속(dependent) transaction은 트랜잭션이 의존하는 transaction보다 먼저 적용될 수 없습니다. 


transaction의 종속 영역은 명백하게 현재 transaction에서 이전에 적용된 transaction을 명시하는것을 허용한다. 명시적 종속성은 transaction이 종속성(dependencies)을 갖고있는 상황에서 유용하지만 같은 batch에 대치될 수 없다(예를들어, transaction이 다른시간에 제출되었다면). 병렬 스케줄링 작업(parallel scheduling operation)을 돕기 위해 transaction의 입력 및 출력 필드에는 state address가 포함됩니다. 스케쥴러는 state와 상호 작용을 기반으로 transaction간의 묵시적 종속성(explicit dependencies)을 결정한다. 주소는 정규화 된 리프-노드(leaf-node)주소 또는 부분 접두사 주소(partial prefix addresses) 일 수 있습니다. input addresses는 state로부터 읽고 output addresses는 state에서 쓰여진다. 그들이 클라이언트로부터 지정되는 동안, transaction에서 input과 output 선언은 transaction 실행동안 시행된다. 부분 주소(Partial addresses)는 와일드 카드로 작동하여 transaction이 리프 노드 대신 트리의 일부를 지정할 수 있습니다.



Payload


payload는 state에 적용되어야하는 변경사항을 전달하는 방법으로 transaction 실행 중에 사용된다. transaction 처리하는 transaction family는 payload에 deserialize 되어있다(나머지 시스템의 모든 컴포넌트에). payload는 bytes의 연속이다.



Nonce 


nonce field는 client로 부터 생성된 랜덤 문자열을 포함하고 있다. 만약 2개의 transaction이 같은 filed에 동일하게 포함되어 있다면, nonce는 transaction이 다른 header signature를 생성하는것을 보장할 것이다. 


Batch Data Structure


batch도 마찬가지고 Protocol Buffer를 사용해서 serialized된다. batch는 두개의 매세지 타입으로 구성되어 있다.


File: protos/batch.proto

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47
48

49

50

51

// Copyright 2016 Intel Corporation

//

// Licensed under the Apache License, Version 2.0 (the "License");

// you may not use this file except in compliance with the License.

// You may obtain a copy of the License at

//

//     http://www.apache.org/licenses/LICENSE-2.0

//

// Unless required by applicable law or agreed to in writing, software

// distributed under the License is distributed on an "AS IS" BASIS,

// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

// See the License for the specific language governing permissions and

// limitations under the License.

// -----------------------------------------------------------------------------


syntax = "proto3";


option java_multiple_files = true;

option java_package = "sawtooth.sdk.protobuf";

option go_package = "batch_pb2";


import "transaction.proto";


message BatchHeader {

    // Public key for the client that signed the BatchHeader

    string signer_public_key = 1;


    // List of transaction.header_signatures that match the order of

    // transactions required for the batch

    repeated string transaction_ids = 2;

}


message Batch {

    // The serialized version of the BlockHeader

    bytes header = 1;


    // The signature derived from signing the header

    string header_signature = 2;


    // A list of the transactions that match the list of

    // transaction_ids listed in the batch header

    repeated Transaction transactions = 3;


    // A debugging flag which indicates this batch should be traced through the

    // system, resulting in a higher level of debugging output.

    bool trace = 4;

}


message BatchList {

    repeated Batch batches = 1;

}



Header, Signature, and Public Keys


트랜잭션에 표시된 패턴 다음에 Batch 헤더 필드는 BatchHeader의 직렬화 된 버전입니다. 헤더는 서명자의 rpvate key로 서명되어있고 서명의 결과는 header_signature에 저장된다. 헤더는 serialized된 형식으로 제공되므로 batch를 수신하면 정확한 바이트를 서명과 비교하여 확인할 수 있습니다.


serialized된 문서의 결과는 secp256k1 curve를 사용해서 transactor의 private ECDSA key와 함께 서명된다.


validator는 64바이트의 "compact" 서명을 필요로 한다(64바이트 경량 서명이 도달할 예정이라는듯). 이 서명에는 R과 S 필드의 서명이 연결되어 있다. 몇개의 라이브러리는 추가적인 헤더 바이트, 복구 ID 영역 또는 DER로 암호화된 서명 제공을 포함하고 있다. Sawtooth는 64비트가 아닌 다른 서명은 보두 거절한다.



Transactions


 transaction 영역은 batch와 알맞는 Transactions의 목록을 포함한다. Transaction은 나열된 순서대로 적용된다. transaction_ids 영역은 Transaction header_signatures의 목록을 포함하고 transaction 필드와 동일한 순서여야 한다.



Why Batches?


 위에서 언급했듯이 일괄처리(batch)는 시스템의 원자 단위 변경이다(세세한 부분을 변경을 할 수 있다는 뜻). 만약 batch가 적용되었다면, 모든 transaction은 batch가 포함된 순서대로 적용된다. 배치가 적용되지 않았다면(아마 transaction중의 하나가 사용불가일 것이다.), transaction이 하나도 적용되지 않을 것 이다. 


 이는 batch 내 transaction이 명시적 종속성(explicit dependencies)을 필요로하지 않으므로 종속 관계 관리를 클라이언트 관점에서 크게 단순화합니다. 결과적으로, 명시적 의존성의 유용성(transaction의 종속성 필드에 포함됨)은 transaction을 동일한 batch에 배치할 수 없는 종속성으로 제한된다. 


 batch는 명시적 종속성과 함께 해결되지 않는 중요한 문제를 해결한다. transaction A, B, C가 있고 원하는 동작이 A, B, C인 순서로 적용된다고 가정하고, 그 중 하나가 유효하지 않은 경우 적용되지 않아야 한다(순서대로 동작을 안하면 작동을 안한다는 의미 같다). 오직 종속성(dependencies)을 사용해서 이 문제를 해결하려고 한다면, 우리는 다음과 같은 관계를 시도 할 수 있다 : C는 B에 의존하고, B는 A에 의존하고, A는 C에 의존한다. 그러나, 종속성 필드는 이 관계를 나타 내기 위해 사용될 수 없기 때문에 종속성은 순서를 적용하고 위는 주기적이므로 순서를 지정할 수 없다.


여러 transaction families의 transaction을 함께 batch처리할 수 있으므로, transaction families의 재사용할 수 있다. 예를 들어, 구성(configuration)을 위한 transaction 또는 identity transaction family는 어플리케이션 특정(application-specific) transaction과 함께 일괄처리(batch)될 수 있다.


Transaction과 batch는 마찬가지로 다른키로부터 서명된다. 예를들어, 브라우저 어플리케이션은 transaction에 서명할 수 있고 서버단 컴포넌트는 transaction 추가, batch생성, batch에 서명을 할 수 있다. 이는 다양한 transaction에서 atomic operation(batch)으로 부터 transaction의 종합을 포함하는 흥미로운 어플리케이션 패턴을 가능하게 한다.


 transaction과 batch 간에는 중요한 제한 사항이 있습니다. transaction에는 batch 서명자의 공개 키가 batcher_public_key 필드에 포함되어야합니다. 이것은 의도 한 batch와 별도로 transaction을 재사용하지 못하도록하기위한 것입니다. 따라서 예를 들어, batcher's의 개인 키(private key)가 없으면 batch에서 transaction을 가져 와서 새로운 batch로 다시 패키징하고 일부 트랜잭션을 생략 할 수 없습니다.