attestation icon indicating copy to clipboard operation
attestation copied to clipboard

DER data object decoder in Solidity

Open SmartLayer opened this issue 4 years ago • 0 comments

Produce the code represented in the ellipsis, which parses a data object.

pragma experimental ABIEncoderV2
struct Ticket {
  uint match;     // from 01 to 51
  uint class;     // club(0), lounge(1), silver(2), gold(3)
  uint admission; // how many people can enter
}

function decodeTicket(bytes der) internal view returns(Ticket) {
  [...]
}

function testDecoder() public view returns(bool) {
  bytes constant der = "0x30090201010a0101020101";
  Ticket ticket =  decodeTicket(bytes der);
  return ticket.match ==1 && ticket.class == 1 && ticket.admission == 01;
}

Testify that shows the bytes being correctly construted DER:

$ echo -n 30090201010a0101020101 | xxd -r -p | openssl asn1parse -inform DER -i
    0:d=0  hl=2 l=   9 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim:  INTEGER           :01
    5:d=1  hl=2 l=   1 prim:  ENUMERATED        :01
    8:d=1  hl=2 l=   1 prim:  INTEGER           :01

This is the python3 code to generate the DER-encoded data:

from pyasn1.codec.der import decoder, encoder
from pyasn1.type.univ import Sequence, OctetString, ObjectIdentifier, Integer, Enumerated
from pyasn1.type.namedtype import NamedTypes, NamedType
from pyasn1.type.namedval import NamedValues

class Class(Enumerated):
    namedValues = NamedValues(
        ('The Club', 0), ('The Lounge', 1),
        ('Gold', 2), ('Silver', 3)
    )

class Ticket(Sequence):
   componentType = NamedTypes(
	NamedType('match', Integer()),
	NamedType('class', Class()),
	NamedType('admission',Integer())
   )

ticket = Ticket()
ticket['match'] = 1
ticket['class'] = 1
ticket['admission'] = 1
print(encoder.encode(ticket).hex())

As you may have noticed I made everything INTEGER to make the work easier to start. Can't avoid the ENUMERATED type though.


An earlier decoder written by James Brown is attached

DerDecode.sol.gz

with the following comments from him:

It has limitations in that any IA5 string decoded has to be 32 bytes or less, and it can only handle up to 40 translation objects. I can fix this in future.

SmartLayer avatar Nov 17 '19 04:11 SmartLayer