# Confusion about smart contracts

**URL:** <https://forum.algorand.co/t/confusion-about-smart-contracts/3600>\
**Category:** Uncategorized\
**Created:** [June 22, 2021, 2:45pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600 "2021-06-22T14:45:14Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 22, 2021, 2:45pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/1 "2021-06-22T14:45:14Z")

</div>

Dear Guys  
I have a problem while learning smart contracts, how can I write and read data structures automatically through smart contracts?  
The data type byte “counter” in the example does not match what I want. Is there a function to define data types in Algorand smart contracts?

---

<div class="post-metadata">

**Author:** ![fabrice](https://avatars.discourse-cdn.com/v4/letter/f/5fc32e/32.png) [@fabrice](https://forum.algorand.co/u/fabrice)\
**Post date:** [June 22, 2021, 5:04pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/2 "2021-06-22T17:04:56Z")

</div>

Stateful smart contracts use key/value storage.  
Each value can store either a byte string or a 64-bit unsigned integer.

If you need to store more complex data structure, you need to manually implement them.

What kind of data structure are you interested in?

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 23, 2021, 2:53am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/3 "2021-06-23T02:53:26Z")

</div>

Thanks,fabrice.  
The key-value pair is exactly what I need, but I may need to store more than one key-value pair, e.g. [student-{1,2,3,4,5}], [teacher-{2,3,4,5,6}]…  
How do I set this manually?  
By the way, when I read the global status of the example byte “counter”, why the result is [{Y291bnRlcg== { 2 1}}]  
What is the meaning of this result?

---

<div class="post-metadata">

**Author:** ![fabrice](https://avatars.discourse-cdn.com/v4/letter/f/5fc32e/32.png) [@fabrice](https://forum.algorand.co/u/fabrice)\
**Post date:** [June 23, 2021, 3:02am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/4 "2021-06-23T03:02:59Z")

</div>

> [@michaelfighting](#):
>
> The key-value pair is exactly what I need, but I may need to store more than one key-value pair, e.g. [student-{1,2,3,4,5}], [teacher-{2,3,4,5,6}]…  
> How do I set this manually?

Do you want to store values associated to keys `student-1`, `student-2`, … ?  
If yes, you need to manually generate the key using TEAL and then use the appropriate op-code to store in the value you want in this key.

Most likely, instead of `student-1`, you want `student-#`, where `#` is a byte equal to 1 (that is a character that cannot be displayed but that can be used as part of the key).

Note that you can store at most 64 global key/values per smart contract.  
If you need more, you need to use local state.

What are you trying to store/achieve?

> [@michaelfighting](#):
>
> By the way, when I read the global status of the example byte “counter”, why the result is [{Y291bnRlcg== { 2 1}}]  
> What is the meaning of this result?

Can you show the code of the smart contract and the way you use to read this value?

My guess is that you printed only the value of the struct representation the global state rather than pretty-printing the actual struct.  
Indeed:

- `Y291bnRlcg==` is the base64 encoding of `counter`. See [Base64 - Wikipedia](https://en.wikipedia.org/wiki/Base64). You can convert base64 on the command line like this:

```bash
base64 -d <<< "Y291bnRlcg=="

```

- 2 and 1 are most likely the fields of `tt` (type) and `ui` (actual data). `tt=2` means it is an integer value (as opposed to bytes), and `ui=1` means that the value of the counter is 1.

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 23, 2021, 3:47am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/5 "2021-06-23T03:47:40Z")

</div>

Thank you very much for your guidance!

I think it is the second one that should be implemented, the trouble is that my value type is a structure  
For example my key-value pair is device\_id-{mac\_address, device\_type}, the concrete example is 123-{2567, 1}.  
Can Algorand smart contract implement such data structure? I have tried it in Ethereum.

Regarding the second question, I think it should be your explanation

---

<div class="post-metadata">

**Author:** ![fabrice](https://avatars.discourse-cdn.com/v4/letter/f/5fc32e/32.png) [@fabrice](https://forum.algorand.co/u/fabrice)\
**Post date:** [June 23, 2021, 4:43am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/6 "2021-06-23T04:43:34Z")

</div>

You need to decide of a format.  
For example, if the value is mac\_address, device\_type, you can decide the value to be the concatenation of both with a space:

`00:1B:44:11:3A:B7 macOS`

for example.  
You can generate it using the `concat` opcode ([Opcodes - Algorand Developer Portal](https://developer.algorand.org/docs/reference/teal/opcodes/#concat)).  
You can do the reverse operation using the `substring` opcode since the MAC address is always the same length.

You may decide to encode the MAC address as 6 bytes rather than 17 bytes.  
This is more compact.  
You may also remove the space.

Note that this technique only work as long as all the fields in your structure have a constant length (the MAC address has a known length of 17 bytes or 6 bytes). If this is not the case, you need more advanced encoding. For example, you can start with 1 byte indicating the length of the field.

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 23, 2021, 7:09am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/7 "2021-06-23T07:09:28Z")

</div>

Thank you  
I understand your point in general, but I may need some time to digest it

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 23, 2021, 2:45pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/8 "2021-06-23T14:45:05Z")

</div>

Hey, fabrice.

I am very happy to have a better understanding of the second question.  
As far as I know, the “counter” I entered is the key of a key-value pair, but I don’t know at which step of my smart contract I get the value 1 and the type 2.  
By the way, if I want to use sdk to output the actual structure of the key-value pair, for example

```json
{
  "counter": {
    "tt": 2,
    "ui": 1
  }

```

what should I do?

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 23, 2021, 2:51pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/9 "2021-06-23T14:51:36Z")

</div>

Also my smart contract code and the way I read the values is as follows.

```auto
// read global state
byte "counter"
dup 
app_global_get 

// increment the value
int 1
+

// store to scratch space
dup
store 0 
// update global state
app_global_put 
// load return value as approval
load 0 
return

```

```auto
func readGlobalState(client *algod.Client, account crypto.Account, index uint64) {
	accountInfo, err := client.AccountInformation(account.Address.String()).Do(context.Background())
	if err != nil {
		fmt.Printf("Error getting account info: %s\n", err)
		return
	}
	for _, ap := range accountInfo.CreatedApps {
		if ap.Id == index {
			fmt.Printf("Global state for app-id %d:\n", ap.Id)
			fmt.Println(ap.Params.GlobalState)
		}
	}
}

```

---

<div class="post-metadata">

**Author:** ![fabrice](https://avatars.discourse-cdn.com/v4/letter/f/5fc32e/32.png) [@fabrice](https://forum.algorand.co/u/fabrice)\
**Post date:** [June 23, 2021, 3:11pm UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/10 "2021-06-23T15:11:48Z")

</div>

To print structure in GoLang:

```auto
fmt.Printf("%#v", ap.Params.GlobalState)

```

or:

```auto
    gs, err := json.MarshalIndent(ap.Params.GlobalState, "", "\t")
    if err != nil {
        fmt.Printf("Can not marshall global state data: %s\n", err)
    }
    fmt.Printf("%s\n", gs)

```

---

<div class="post-metadata">

**Author:** ![michaelfighting](https://avatars.discourse-cdn.com/v4/letter/m/8baadc/32.png) [@michaelfighting](https://forum.algorand.co/u/michaelfighting)\
**Post date:** [June 24, 2021, 3:33am UTC](https://forum.algorand.co/t/confusion-about-smart-contracts/3600/11 "2021-06-24T03:33:43Z")

</div>

Thanks for your help
