github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/common/util/utils.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"crypto/rand"
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  	"strings"
    25  	"time"
    26  
    27  	"github.com/golang/protobuf/ptypes/timestamp"
    28  	"github.com/hyperledger/fabric/bccsp"
    29  	"github.com/hyperledger/fabric/bccsp/factory"
    30  	"github.com/hyperledger/fabric/common/metadata"
    31  )
    32  
    33  type alg struct {
    34  	hashFun func([]byte) string
    35  }
    36  
    37  const defaultAlg = "sha256"
    38  
    39  var availableIDgenAlgs = map[string]alg{
    40  	defaultAlg: {GenerateIDfromTxSHAHash},
    41  }
    42  
    43  // ComputeSHA256 returns SHA2-256 on data
    44  func ComputeSHA256(data []byte) (hash []byte) {
    45  	hash, err := factory.GetDefault().Hash(data, &bccsp.SHA256Opts{})
    46  	if err != nil {
    47  		panic(fmt.Errorf("Failed computing SHA256 on [% x]", data))
    48  	}
    49  	return
    50  }
    51  
    52  // ComputeSHA3256 returns SHA3-256 on data
    53  func ComputeSHA3256(data []byte) (hash []byte) {
    54  	hash, err := factory.GetDefault().Hash(data, &bccsp.SHA3_256Opts{})
    55  	if err != nil {
    56  		panic(fmt.Errorf("Failed computing SHA3_256 on [% x]", data))
    57  	}
    58  	return
    59  }
    60  
    61  // GenerateBytesUUID returns a UUID based on RFC 4122 returning the generated bytes
    62  func GenerateBytesUUID() []byte {
    63  	uuid := make([]byte, 16)
    64  	_, err := io.ReadFull(rand.Reader, uuid)
    65  	if err != nil {
    66  		panic(fmt.Sprintf("Error generating UUID: %s", err))
    67  	}
    68  
    69  	// variant bits; see section 4.1.1
    70  	uuid[8] = uuid[8]&^0xc0 | 0x80
    71  
    72  	// version 4 (pseudo-random); see section 4.1.3
    73  	uuid[6] = uuid[6]&^0xf0 | 0x40
    74  
    75  	return uuid
    76  }
    77  
    78  // GenerateIntUUID returns a UUID based on RFC 4122 returning a big.Int
    79  func GenerateIntUUID() *big.Int {
    80  	uuid := GenerateBytesUUID()
    81  	z := big.NewInt(0)
    82  	return z.SetBytes(uuid)
    83  }
    84  
    85  // GenerateUUID returns a UUID based on RFC 4122
    86  func GenerateUUID() string {
    87  	uuid := GenerateBytesUUID()
    88  	return idBytesToStr(uuid)
    89  }
    90  
    91  // CreateUtcTimestamp returns a google/protobuf/Timestamp in UTC
    92  func CreateUtcTimestamp() *timestamp.Timestamp {
    93  	now := time.Now().UTC()
    94  	secs := now.Unix()
    95  	nanos := int32(now.UnixNano() - (secs * 1000000000))
    96  	return &(timestamp.Timestamp{Seconds: secs, Nanos: nanos})
    97  }
    98  
    99  //GenerateHashFromSignature returns a hash of the combined parameters
   100  func GenerateHashFromSignature(path string, args []byte) []byte {
   101  	return ComputeSHA256(args)
   102  }
   103  
   104  // GenerateIDfromTxSHAHash generates SHA256 hash using Tx payload
   105  func GenerateIDfromTxSHAHash(payload []byte) string {
   106  	return fmt.Sprintf("%x", ComputeSHA256(payload))
   107  }
   108  
   109  // GenerateIDWithAlg generates an ID using a custom algorithm
   110  func GenerateIDWithAlg(customIDgenAlg string, payload []byte) (string, error) {
   111  	if customIDgenAlg == "" {
   112  		customIDgenAlg = defaultAlg
   113  	}
   114  	var alg = availableIDgenAlgs[customIDgenAlg]
   115  	if alg.hashFun != nil {
   116  		return alg.hashFun(payload), nil
   117  	}
   118  	return "", fmt.Errorf("Wrong ID generation algorithm was given: %s", customIDgenAlg)
   119  }
   120  
   121  func idBytesToStr(id []byte) string {
   122  	return fmt.Sprintf("%x-%x-%x-%x-%x", id[0:4], id[4:6], id[6:8], id[8:10], id[10:])
   123  }
   124  
   125  // FindMissingElements identifies the elements of the first slice that are not present in the second
   126  // The second slice is expected to be a subset of the first slice
   127  func FindMissingElements(all []string, some []string) (delta []string) {
   128  all:
   129  	for _, v1 := range all {
   130  		for _, v2 := range some {
   131  			if strings.Compare(v1, v2) == 0 {
   132  				continue all
   133  			}
   134  		}
   135  		delta = append(delta, v1)
   136  	}
   137  	return
   138  }
   139  
   140  // ToChaincodeArgs converts string args to []byte args
   141  func ToChaincodeArgs(args ...string) [][]byte {
   142  	bargs := make([][]byte, len(args))
   143  	for i, arg := range args {
   144  		bargs[i] = []byte(arg)
   145  	}
   146  	return bargs
   147  }
   148  
   149  // ArrayToChaincodeArgs converts array of string args to array of []byte args
   150  func ArrayToChaincodeArgs(args []string) [][]byte {
   151  	bargs := make([][]byte, len(args))
   152  	for i, arg := range args {
   153  		bargs[i] = []byte(arg)
   154  	}
   155  	return bargs
   156  }
   157  
   158  const testchainid = "testchainid"
   159  const testorgid = "**TEST_ORGID**"
   160  
   161  //GetTestChainID returns the CHAINID constant in use by orderer
   162  func GetTestChainID() string {
   163  	return testchainid
   164  }
   165  
   166  //GetTestOrgID returns the ORGID constant in use by gossip join message
   167  func GetTestOrgID() string {
   168  	return testorgid
   169  }
   170  
   171  //GetSysCCVersion returns the version of all system chaincodes
   172  //This needs to be revisited on policies around system chaincode
   173  //"upgrades" from user and relationship with "fabric" upgrade. For
   174  //now keep it simple and use the fabric's version stamp
   175  func GetSysCCVersion() string {
   176  	return metadata.Version
   177  }
   178  
   179  // ConcatenateBytes is useful for combining multiple arrays of bytes, especially for
   180  // signatures or digests over multiple fields
   181  func ConcatenateBytes(data ...[]byte) []byte {
   182  	finalLength := 0
   183  	for _, slice := range data {
   184  		finalLength += len(slice)
   185  	}
   186  	result := make([]byte, finalLength)
   187  	last := 0
   188  	for _, slice := range data {
   189  		for i := range slice {
   190  			result[i+last] = slice[i]
   191  		}
   192  		last += len(slice)
   193  	}
   194  	return result
   195  }