# Actor Spec: Init
[Back to Master Tracking Doc](https://hackmd.io/LOZjAsz-THelSD5lWqSVlw)
## Contents
[TOC]
## At a Glance
The Init actor plays an important role as the ONLY actor able to create other actors. Specifically, the Init actor must be used to create any of the following Instanced actors:
* PaymentChannel actor
* Multisig actor
* Miner actor
Note that the Account actor, which is also Instanced, is not created explicitly through the Init actor's Exec method. Instead, Account actors are created implicitly whenever a top-level message invokes a method on an actor that does not exist yet.
**Actor Type:**
- Singleton
- Address: 1
**Exported Methods:**
1. Constructor
2. Exec
## State
```go=
type State struct {
AddressMap cid.Cid
NextID abi.ActorID
NetworkName string
}
```
**`AddressMap`**: Often referred to as the "Init actor's table". Maintains a reference of all actors created via the Init actor, as well as all created Account actors.
* Notes:
* Cid type: HAMT, `map[Address]ActorID`
* For actors created via Init.Exec, maps the actor's ACTOR address to its ID address
* For an Account actor, maps the actor's BLS/SECP address to its ID address
**`NextID`**: The ActorID that will be assigned to the next created actor.
* Notes:
* Each time an actor is created, it is assigned the ActorID `NextID`.
* Each time an actor is created, `NextID` is incremented by 1.
* Invariants:
* `NextID >= 100` (see `builtin.FirstNonSingletonActorId`)
**`NetworkName`**: Arbitrary network name value. Actual value TBD.
## Exported Methods
#### 1. Constructor
```go=
func (a Actor) Constructor(rt runtime.Runtime, params *ConstructorParams) *adt.EmptyValue
```
The Init constructor initializes `State` with the actor's `NetworkName`, and sets `st.NextID` to 100. New actors will be assigned sequential ID addresses, starting with this value.
##### Parameters
```go=
type ConstructorParams struct {
NetworkName string
}
```
**`NetworkName`**: Arbitrary network name value. Actual value TBD.
#### 2. Exec
```go=
func (a Actor) Exec(rt runtime.Runtime, params *ExecParams) *ExecReturn
```
Used to create new actors.
* The Init actor implements restrictions based on the Caller's CodeCID
* The newly-created actor is given two addresses:
* A canonical ID address used to reference the actor internally
* An ACTOR address - a more expensive but re-org-safe address.
* Also referred to as a "unique" address, or a "robust" address
* Created via `rt.NewActorAddress()`
* The newly-created actor's constructor is also passed TokenAmount `Message().ValueReceived()`
##### Parameters
```go=
type ExecParams struct {
CodeCID cid.Cid
ConstructorParams []byte
}
```
**`CodeCID`**: The CID of the code the Caller wishes to instantiate
* Notes:
* Cid type: Special. See `builtin/codes.go`.
* Requirements:
* If `CodeCID` refers to the Miner actor, Caller must be the Power actor.
* If `CodeCID` refers to the PaymentChannel or Multisig actors, no requirements exist.
* If `CodeCID` is any other value, method will fail.
**`ConstructorParams`**: The parameters that will be sent to the created actor's Constructor.
* Requirements:
* No validation is performed on this value, but the new actor's Constructor must succeed when invoked with these parameters.
##### Return
```go=
type ExecReturn struct {
IDAddress addr.Address
RobustAddress addr.Address
}
```
**`IDAddress`**: The newly-created actor's ID address.
* Notes:
* Is unique for each successful execution of Init.Exec
* Is created from `st.NextID`
**`RobustAddress`**: The newly-created actor's ACTOR address.
* Notes:
* Created using `rt.NewActorAddress()`
##### Failure conditions
* Caller does not have a CodeCID (`rt.GetActorCodeCID(Caller)` fails)
* Caller attempts to create a Miner actor, but Caller is not the Power actor.
* Caller attempts to create any other actor except Multisig / PaymentChannel
* Created actor's constructor fails
## Questions
* How are the first instances of instanced actors created? Their constructors require that the Init actor be the caller.
* anorth: In genesis state, where we can fake it
* Can I use an ID Address to invoke a method on an actor from a top-level message, or do I need to use an Actor Address?
* why: You can use either.
* If I want to send an Account actor some FIL through a top-level message, what address protocols can I use to refer to the Account actor?
* anorth: If the Account actor doesn't exist, you can use BLS or SECP and the actor will be implicitly created and added to the init actor table.
* If the Account actor does exist, you can use BLS, SECP, or an ID address.
* Account actors do not have ACTOR Addresses.