diff --git a/Gopkg.lock b/Gopkg.lock index ac4f2f285d14ed8b28b9331e02b41f7106c6ba3d..fb5c586a4249ae7666a6417bb8d71f131b348b1f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -31,7 +31,7 @@ name = "github.com/btcsuite/btcd" packages = ["btcec"] pruneopts = "NUT" - revision = "f673a4b563b57b9a95832545c878669a7fa801d9" + revision = "9a2f9524024889e129a5422aca2cff73cb3eabf6" [[projects]] branch = "master" @@ -436,7 +436,7 @@ "ssh/terminal", ] pruneopts = "NUT" - revision = "a2144134853fc9a27a7b1e3eb4f19f1a76df13c9" + revision = "c126467f60eb25f8f27e5a981f32a87e3965053f" [[projects]] digest = "1:15dbe437d38eb2103f6b55348758958a6f85a400ecc16fcb53b3f271d38cd8ea" @@ -495,7 +495,7 @@ name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] pruneopts = "NUT" - revision = "fedd2861243fd1a8152376292b921b394c7bef7e" + revision = "02b4e95473316948020af0b7a4f0f22c73929b0e" [[projects]] digest = "1:f778941d5c2e46da5e0f5d553d3e80bf70eb40d2e80bb4c649b625b9133f3d5f" @@ -552,7 +552,9 @@ "github.com/go-kit/kit/log/term", "github.com/gogo/protobuf/gogoproto", "github.com/gogo/protobuf/proto", + "github.com/gogo/protobuf/types", "github.com/golang/protobuf/proto", + "github.com/golang/protobuf/ptypes/timestamp", "github.com/gorilla/websocket", "github.com/howeyc/gopass", "github.com/imdario/mergo", diff --git a/Makefile b/Makefile index fcc9956dd5a37a02ae95ffb288d57712202355ef..3db456789da99d0d0a401b9074d08210c8db3833 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ protobuf_deps: # Implicit compile rule for GRPC/proto files (note since pb.go files no longer generated # in same directory as proto file this just regenerates everything %.pb.go: %.proto - protoc -I vendor -I protobuf $< --gogo_out=plugins=grpc:${GOPATH}/src + protoc -I protobuf -I vendor $< --gogo_out=plugins=grpc:${GOPATH}/src .PHONY: protobuf protobuf: $(PROTO_GO_FILES) diff --git a/execution/contexts/permissions_context.go b/execution/contexts/permissions_context.go index 00cbd1a5589823ba72a7d59f55e361a59238c197..ac4c450b3adf904ba0d85f776aac597e62804a2e 100644 --- a/execution/contexts/permissions_context.go +++ b/execution/contexts/permissions_context.go @@ -44,7 +44,7 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error { return fmt.Errorf("PermsTx received containing invalid PermArgs: %v", err) } - permFlag := ctx.tx.PermArgs.PermFlag + permFlag := ctx.tx.PermArgs.Action // check permission if !HasPermission(ctx.StateWriter, inAcc, permFlag, ctx.Logger) { return fmt.Errorf("account %s does not have moderator permission %s (%b)", ctx.tx.Input.Address, @@ -65,17 +65,17 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error { "perm_args", ctx.tx.PermArgs.String()) var permAcc acm.Account - switch ctx.tx.PermArgs.PermFlag { + switch ctx.tx.PermArgs.Action { case permission.HasBase: // this one doesn't make sense from txs return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain") case permission.SetBase: - permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, + permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target, func(perms *permission.AccountPermissions) error { return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value) }) case permission.UnsetBase: - permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, + permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target, func(perms *permission.AccountPermissions) error { return perms.Base.Unset(*ctx.tx.PermArgs.Permission) }) @@ -87,20 +87,20 @@ func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error { case permission.HasRole: return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain") case permission.AddRole: - permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, + permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target, func(perms *permission.AccountPermissions) error { if !perms.AddRole(*ctx.tx.PermArgs.Role) { return fmt.Errorf("role (%s) already exists for account %s", - *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address) + *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Target) } return nil }) case permission.RemoveRole: - permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, + permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Target, func(perms *permission.AccountPermissions) error { if !perms.RmRole(*ctx.tx.PermArgs.Role) { return fmt.Errorf("role (%s) does not exist for account %s", - *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address) + *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Target) } return nil }) diff --git a/permission/permission.pb.go b/permission/permission.pb.go index b72986011d0be70e3ed447ac9745961bd7388b3e..da42a596ccca8986f5ed7f27f39077291efab47e 100644 --- a/permission/permission.pb.go +++ b/permission/permission.pb.go @@ -94,20 +94,23 @@ func (*BasePermissions) XXX_MessageName() string { } type PermArgs struct { - PermFlag PermFlag `protobuf:"varint,1,opt,name=PermFlag,casttype=PermFlag" json:"PermFlag"` - Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"` - Permission *PermFlag `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"` - Role *string `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"` - Value *bool `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"` + // The permission function + Action PermFlag `protobuf:"varint,1,opt,name=Action,casttype=PermFlag" json:"Action"` + // The target of the action + Target *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Target,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Target,omitempty"` + // Possible arguments + Permission *PermFlag `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"` + Role *string `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"` + Value *bool `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"` } func (m *PermArgs) Reset() { *m = PermArgs{} } func (*PermArgs) ProtoMessage() {} func (*PermArgs) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{2} } -func (m *PermArgs) GetPermFlag() PermFlag { +func (m *PermArgs) GetAction() PermFlag { if m != nil { - return m.PermFlag + return m.Action } return 0 } @@ -232,12 +235,12 @@ func (m *PermArgs) MarshalTo(dAtA []byte) (int, error) { _ = l dAtA[i] = 0x8 i++ - i = encodeVarintPermission(dAtA, i, uint64(m.PermFlag)) - if m.Address != nil { + i = encodeVarintPermission(dAtA, i, uint64(m.Action)) + if m.Target != nil { dAtA[i] = 0x12 i++ - i = encodeVarintPermission(dAtA, i, uint64(m.Address.Size())) - n2, err := m.Address.MarshalTo(dAtA[i:]) + i = encodeVarintPermission(dAtA, i, uint64(m.Target.Size())) + n2, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -307,9 +310,9 @@ func (m *BasePermissions) Size() (n int) { func (m *PermArgs) Size() (n int) { var l int _ = l - n += 1 + sovPermission(uint64(m.PermFlag)) - if m.Address != nil { - l = m.Address.Size() + n += 1 + sovPermission(uint64(m.Action)) + if m.Target != nil { + l = m.Target.Size() n += 1 + l + sovPermission(uint64(l)) } if m.Permission != nil { @@ -568,9 +571,9 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PermFlag", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) } - m.PermFlag = 0 + m.Action = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPermission @@ -580,14 +583,14 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.PermFlag |= (PermFlag(b) & 0x7F) << shift + m.Action |= (PermFlag(b) & 0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -612,8 +615,8 @@ func (m *PermArgs) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } var v github_com_hyperledger_burrow_crypto.Address - m.Address = &v - if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Target = &v + if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -818,27 +821,28 @@ func init() { proto.RegisterFile("permission.proto", fileDescriptorPermission) } func init() { golang_proto.RegisterFile("permission.proto", fileDescriptorPermission) } var fileDescriptorPermission = []byte{ - // 351 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x31, 0x4b, 0xc3, 0x40, - 0x14, 0xee, 0xb5, 0xa9, 0xb6, 0xcf, 0x82, 0xe5, 0x70, 0x08, 0x0a, 0x49, 0xe8, 0x20, 0x19, 0x6a, - 0x22, 0x82, 0x4b, 0x07, 0xa1, 0x19, 0x1c, 0x9c, 0xe4, 0x04, 0x07, 0xb7, 0x34, 0x3d, 0xd3, 0x40, - 0xda, 0x0b, 0x77, 0x17, 0xa4, 0xff, 0xc4, 0x51, 0xff, 0x89, 0x63, 0xc7, 0xce, 0x0e, 0x45, 0x5a, - 0xf0, 0x47, 0x38, 0xc9, 0x5d, 0x6a, 0x1b, 0x85, 0xba, 0xbd, 0xef, 0x7d, 0xdf, 0x7b, 0xdf, 0xbd, - 0xef, 0xa0, 0x9d, 0x51, 0x3e, 0x4e, 0x84, 0x48, 0xd8, 0xc4, 0xcb, 0x38, 0x93, 0x0c, 0xc3, 0xb6, - 0x73, 0x7c, 0x16, 0x27, 0x72, 0x94, 0x0f, 0xbc, 0x88, 0x8d, 0xfd, 0x98, 0xc5, 0xcc, 0xd7, 0x92, - 0x41, 0xfe, 0xa8, 0x91, 0x06, 0xba, 0x2a, 0x46, 0x3b, 0x21, 0xe0, 0x7e, 0x14, 0xb1, 0x7c, 0x22, - 0x6f, 0x37, 0x3b, 0x04, 0xbe, 0x04, 0x23, 0x08, 0x05, 0x35, 0x91, 0x83, 0xdc, 0x83, 0x8b, 0x13, - 0xaf, 0xe4, 0xa8, 0xfa, 0x25, 0x69, 0x60, 0xcc, 0x16, 0x76, 0x85, 0x68, 0x39, 0x3e, 0x82, 0x3a, - 0x61, 0x29, 0x15, 0x66, 0xd5, 0xa9, 0xb9, 0x4d, 0x52, 0x80, 0x4e, 0x02, 0x87, 0x7f, 0x86, 0xf0, - 0x29, 0xd4, 0x15, 0x14, 0xda, 0xc0, 0x08, 0xda, 0x6a, 0xc7, 0xd7, 0xc2, 0x6e, 0xa8, 0xe6, 0x75, - 0x1a, 0xc6, 0xa4, 0xa0, 0xb1, 0x0b, 0x7b, 0x77, 0x54, 0x06, 0x89, 0x34, 0xab, 0x3b, 0x84, 0x6b, - 0xbe, 0x67, 0x3c, 0xbf, 0xd8, 0x95, 0xce, 0x27, 0x02, 0x4d, 0xf5, 0x79, 0x2c, 0x70, 0x17, 0x36, - 0xb2, 0x9d, 0x3e, 0x9b, 0x0a, 0xdf, 0xc0, 0x7e, 0x7f, 0x38, 0xe4, 0x54, 0x08, 0xed, 0xd5, 0x0a, - 0xce, 0xdf, 0x17, 0x76, 0xb7, 0x14, 0xe6, 0x68, 0x9a, 0x51, 0x9e, 0xd2, 0x61, 0x4c, 0xb9, 0x3f, - 0xc8, 0x39, 0x67, 0x4f, 0x7e, 0xc4, 0xa7, 0x99, 0x64, 0xde, 0x7a, 0x8e, 0xfc, 0x2c, 0xc0, 0x5d, - 0x80, 0xed, 0xb5, 0x66, 0x4d, 0x7b, 0xb7, 0x7e, 0xf9, 0x96, 0x78, 0x8c, 0xc1, 0x50, 0x41, 0x99, - 0x86, 0x83, 0xdc, 0x26, 0xd1, 0xb5, 0x4a, 0xf2, 0x3e, 0x4c, 0x73, 0x6a, 0xd6, 0x1d, 0xe4, 0x36, - 0x48, 0x01, 0x7a, 0x0d, 0x75, 0xe4, 0xfc, 0xd5, 0xae, 0x04, 0x57, 0xb3, 0xa5, 0x85, 0xe6, 0x4b, - 0x0b, 0x7d, 0x2c, 0x2d, 0xf4, 0xb6, 0xb2, 0xd0, 0x6c, 0x65, 0xa1, 0x07, 0xf7, 0xff, 0xe7, 0x6e, - 0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf4, 0x5f, 0xe9, 0x44, 0x02, 0x00, 0x00, + // 355 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0xb1, 0x4b, 0xfb, 0x40, + 0x14, 0xee, 0xb5, 0x69, 0x69, 0xdf, 0xaf, 0xf0, 0x2b, 0x87, 0x43, 0x50, 0x48, 0x42, 0x07, 0xc9, + 0x50, 0x13, 0x11, 0x5c, 0x3a, 0x08, 0xc9, 0x20, 0x8e, 0x12, 0xc5, 0xc1, 0x2d, 0x4d, 0xcf, 0x6b, + 0x20, 0xed, 0x85, 0xbb, 0x0b, 0xd2, 0xff, 0xc4, 0x51, 0xff, 0x13, 0xc7, 0x8e, 0x9d, 0x1d, 0x4a, + 0x69, 0xff, 0x0b, 0x27, 0xb9, 0x4b, 0xb1, 0x51, 0xa8, 0xdb, 0xfb, 0xde, 0xf7, 0x7d, 0xef, 0xbb, + 0xf7, 0x0e, 0x7a, 0x39, 0xe1, 0xd3, 0x54, 0x88, 0x94, 0xcd, 0xbc, 0x9c, 0x33, 0xc9, 0x30, 0xec, + 0x3b, 0xc7, 0x67, 0x34, 0x95, 0x93, 0x62, 0xe4, 0x25, 0x6c, 0xea, 0x53, 0x46, 0x99, 0xaf, 0x25, + 0xa3, 0xe2, 0x49, 0x23, 0x0d, 0x74, 0x55, 0x5a, 0xfb, 0x31, 0xe0, 0x20, 0x49, 0x58, 0x31, 0x93, + 0xb7, 0xdf, 0x33, 0x04, 0xbe, 0x04, 0x23, 0x8c, 0x05, 0x31, 0x91, 0x83, 0xdc, 0x7f, 0x17, 0x27, + 0x5e, 0x25, 0x51, 0xf5, 0x2b, 0xd2, 0xd0, 0x58, 0xac, 0xec, 0x5a, 0xa4, 0xe5, 0xf8, 0x08, 0x9a, + 0x11, 0xcb, 0x88, 0x30, 0xeb, 0x4e, 0xc3, 0xed, 0x44, 0x25, 0xe8, 0xa7, 0xf0, 0xff, 0x97, 0x09, + 0x9f, 0x42, 0x53, 0x41, 0xa1, 0x03, 0x8c, 0xb0, 0xa7, 0x66, 0x7c, 0xae, 0xec, 0xb6, 0x6a, 0x5e, + 0x67, 0x31, 0x8d, 0x4a, 0x1a, 0xbb, 0xd0, 0xba, 0x23, 0x32, 0x4c, 0xa5, 0x59, 0x3f, 0x20, 0xdc, + 0xf1, 0x43, 0xe3, 0xe5, 0xd5, 0xae, 0xf5, 0xd7, 0x08, 0x34, 0x15, 0x70, 0xaa, 0xcd, 0x41, 0x22, + 0x53, 0x36, 0x3b, 0x98, 0xb2, 0xe3, 0xf1, 0x0d, 0xb4, 0xee, 0x63, 0x4e, 0x49, 0x19, 0xd3, 0x0d, + 0xcf, 0x3f, 0x56, 0xf6, 0xa0, 0x72, 0xc7, 0xc9, 0x3c, 0x27, 0x3c, 0x23, 0x63, 0x4a, 0xb8, 0x3f, + 0x2a, 0x38, 0x67, 0xcf, 0x7e, 0xc2, 0xe7, 0xb9, 0x64, 0x5e, 0x30, 0x1e, 0x73, 0x22, 0x44, 0xb4, + 0xf3, 0xe3, 0x01, 0xc0, 0x7e, 0x4f, 0xb3, 0xa1, 0x73, 0xbb, 0x3f, 0x32, 0x2b, 0x3c, 0xc6, 0x60, + 0xa8, 0x13, 0x99, 0x86, 0x83, 0xdc, 0x4e, 0xa4, 0x6b, 0x75, 0xc3, 0x87, 0x38, 0x2b, 0x88, 0xd9, + 0x74, 0x90, 0xdb, 0x8e, 0x4a, 0x30, 0x6c, 0xab, 0xf5, 0x96, 0x6f, 0x76, 0x2d, 0xbc, 0x5a, 0x6c, + 0x2c, 0xb4, 0xdc, 0x58, 0x68, 0xbd, 0xb1, 0xd0, 0xfb, 0xd6, 0x42, 0x8b, 0xad, 0x85, 0x1e, 0xdd, + 0xbf, 0x5f, 0xbb, 0xff, 0xbf, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x70, 0x53, 0xf2, 0x3e, + 0x02, 0x00, 0x00, } diff --git a/permission/snatives.go b/permission/snatives.go index 6f3df0a1ec184c07c3f0975a1e3c7693cdb3287a..649fcc111f0084f25c0b0c51c689ad5d18347c3a 100644 --- a/permission/snatives.go +++ b/permission/snatives.go @@ -26,9 +26,9 @@ import ( func (pa PermArgs) String() string { body := make([]string, 0, 5) - body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.PermFlag))) - if pa.Address != nil { - body = append(body, fmt.Sprintf("Address: %s", *pa.Address)) + body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.Action))) + if pa.Target != nil { + body = append(body, fmt.Sprintf("Address: %s", *pa.Target)) } if pa.Permission != nil { body = append(body, fmt.Sprintf("Permission: %v", String(*pa.Permission))) @@ -43,9 +43,9 @@ func (pa PermArgs) String() string { } func (pa PermArgs) EnsureValid() error { - pf := pa.PermFlag + pf := pa.Action // Address - if pa.Address == nil && pf != SetGlobal { + if pa.Target == nil && pf != SetGlobal { return fmt.Errorf("PermArgs for PermFlag %v requires Address to be provided but was nil", pf) } if pf == HasRole || pf == AddRole || pf == RemoveRole { @@ -65,16 +65,16 @@ func (pa PermArgs) EnsureValid() error { func HasBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs { return PermArgs{ - PermFlag: HasBase, - Address: &address, + Action: HasBase, + Target: &address, Permission: &permFlag, } } func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs { return PermArgs{ - PermFlag: SetBase, - Address: &address, + Action: SetBase, + Target: &address, Permission: &permFlag, Value: &value, } @@ -82,15 +82,15 @@ func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs func UnsetBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs { return PermArgs{ - PermFlag: UnsetBase, - Address: &address, + Action: UnsetBase, + Target: &address, Permission: &permFlag, } } func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs { return PermArgs{ - PermFlag: SetGlobal, + Action: SetGlobal, Permission: &permFlag, Value: &value, } @@ -98,24 +98,24 @@ func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs { func HasRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: HasRole, - Address: &address, - Role: &role, + Action: HasRole, + Target: &address, + Role: &role, } } func AddRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: AddRole, - Address: &address, - Role: &role, + Action: AddRole, + Target: &address, + Role: &role, } } func RemoveRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: RemoveRole, - Address: &address, - Role: &role, + Action: RemoveRole, + Target: &address, + Role: &role, } } diff --git a/protobuf/permission.proto b/protobuf/permission.proto index d7ba52af5dd3ace0ffcb79596c26a819a263ceb6..b1709bffea4c90d68336dfdc585942842cb3de64 100644 --- a/protobuf/permission.proto +++ b/protobuf/permission.proto @@ -31,8 +31,11 @@ message BasePermissions { message PermArgs { option (gogoproto.goproto_unrecognized) = false; option (gogoproto.goproto_stringer) = false; - optional uint64 PermFlag = 1 [(gogoproto.casttype) = "PermFlag", (gogoproto.nullable) = false]; - optional bytes Address = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/crypto.Address"]; + // The permission function + optional uint64 Action = 1 [(gogoproto.casttype) = "PermFlag", (gogoproto.nullable) = false]; + // The target of the action + optional bytes Target = 2 [(gogoproto.customtype) = "github.com/hyperledger/burrow/crypto.Address"]; + // Possible arguments optional uint64 Permission = 3 [(gogoproto.casttype) = "PermFlag"]; optional string Role = 4; optional bool Value = 5;